From 853b1b7b15723e982f1c2bd91d1b36a363ce2ac6 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Mon, 16 Aug 2021 13:47:16 +0200 Subject: [PATCH 01/50] Initial attempt to build it with Qt6 --- libnymea-app/appdata.cpp | 2 +- libnymea-app/appdata.h | 2 +- libnymea-app/configuration/networkmanager.h | 6 +- .../configuration/nymeaconfiguration.h | 4 +- .../connection/bluetoothtransport.cpp | 6 +- .../connection/discovery/nymeadiscovery.cpp | 5 +- .../connection/discovery/nymeadiscovery.h | 2 +- .../connection/discovery/upnpdiscovery.cpp | 18 +- .../connection/discovery/upnpdiscovery.h | 4 +- .../discovery/zeroconfdiscovery.cpp | 8 +- libnymea-app/connection/nymeaconnection.cpp | 85 +++++++-- libnymea-app/connection/nymeaconnection.h | 5 +- libnymea-app/connection/nymeahosts.cpp | 135 -------------- libnymea-app/connection/nymeahosts.h | 2 - .../connection/nymeatransportinterface.h | 1 + .../connection/tcpsockettransport.cpp | 3 +- libnymea-app/energy/energymanager.h | 2 +- libnymea-app/engine.cpp | 30 +++- libnymea-app/engine.h | 15 +- libnymea-app/interfacesmodel.h | 5 +- libnymea-app/jsonrpc/jsonrpcclient.cpp | 25 +-- libnymea-app/jsonrpc/jsonrpcclient.h | 7 +- libnymea-app/libnymea-app-core.h | 1 + libnymea-app/libnymea-app.pri | 2 + libnymea-app/modbus/modbusrtumanager.cpp | 2 +- libnymea-app/modbus/modbusrtumanager.h | 6 +- libnymea-app/models/barseriesadapter.cpp | 6 +- libnymea-app/models/barseriesadapter.h | 14 +- libnymea-app/models/interfacesproxy.h | 4 +- libnymea-app/models/logsmodel.cpp | 4 +- libnymea-app/models/logsmodel.h | 3 +- libnymea-app/models/logsmodelng.cpp | 20 +-- libnymea-app/models/logsmodelng.h | 15 +- libnymea-app/models/nymeahostsfiltermodel.cpp | 138 +++++++++++++++ libnymea-app/models/nymeahostsfiltermodel.h | 54 ++++++ libnymea-app/models/rulesfiltermodel.h | 3 +- libnymea-app/models/sortfilterproxymodel.cpp | 2 +- libnymea-app/models/taglistmodel.h | 2 +- libnymea-app/models/tagsproxymodel.cpp | 4 +- libnymea-app/models/tagsproxymodel.h | 3 +- .../models/wirelessaccesspointsproxy.h | 3 +- libnymea-app/models/xyseriesadapter.cpp | 12 +- libnymea-app/models/xyseriesadapter.h | 20 ++- libnymea-app/rulemanager.cpp | 8 +- .../ruletemplates/ruleactiontemplate.h | 3 +- libnymea-app/ruletemplates/ruletemplate.h | 8 +- libnymea-app/ruletemplates/ruletemplates.h | 2 +- .../ruletemplates/timedescriptortemplate.h | 4 +- libnymea-app/scripting/codecompletion.cpp | 128 +++++++------- libnymea-app/scripting/codecompletion.h | 3 +- libnymea-app/scripting/scriptautosaver.cpp | 3 +- libnymea-app/scriptmanager.h | 3 +- libnymea-app/system/systemcontroller.h | 5 +- libnymea-app/tagsmanager.cpp | 8 +- libnymea-app/tagwatcher.h | 1 + libnymea-app/thingdiscovery.cpp | 4 +- libnymea-app/thingmanager.cpp | 22 +-- libnymea-app/thingmanager.h | 4 +- libnymea-app/thingsproxy.cpp | 10 +- libnymea-app/thingsproxy.h | 3 +- libnymea-app/types/calendaritem.h | 2 +- libnymea-app/types/interface.h | 7 +- libnymea-app/types/ioconnectionwatcher.h | 4 +- libnymea-app/types/networkdevice.h | 4 +- libnymea-app/types/param.h | 2 +- libnymea-app/types/paramdescriptors.cpp | 4 +- libnymea-app/types/paramdescriptors.h | 4 +- libnymea-app/types/rule.cpp | 36 ++-- libnymea-app/types/rule.h | 8 +- libnymea-app/types/ruleaction.h | 2 +- libnymea-app/types/ruleactionparams.cpp | 6 +- libnymea-app/types/ruleactionparams.h | 6 +- libnymea-app/types/stateevaluator.h | 4 +- libnymea-app/types/tags.cpp | 2 +- libnymea-app/types/tags.h | 2 +- libnymea-app/types/thing.cpp | 16 +- libnymea-app/types/thing.h | 3 +- libnymea-app/types/thingclass.cpp | 2 +- libnymea-app/types/thingclass.h | 2 +- libnymea-app/types/timedescriptor.h | 4 +- libnymea-app/types/timeeventitem.h | 2 +- libnymea-app/usermanager.cpp | 2 +- .../wifisetup/bluetoothdeviceinfos.cpp | 4 +- libnymea-app/wifisetup/bluetoothdeviceinfos.h | 3 +- libnymea-app/wifisetup/btwifisetup.cpp | 28 +-- libnymea-app/wifisetup/btwifisetup.h | 7 +- libnymea-app/zigbee/zigbeeadaptersproxy.h | 3 +- libnymea-app/zigbee/zigbeemanager.h | 8 +- libnymea-app/zigbee/zigbeenodes.h | 2 + libnymea-app/zigbee/zigbeenodesproxy.h | 2 +- nymea-app/dashboard/dashboarditem.h | 2 +- nymea-app/main.cpp | 8 + nymea-app/nfchelper.cpp | 4 + nymea-app/nfcthingactionwriter.cpp | 37 ++-- nymea-app/resources.qrc | 1 + nymea-app/ui/MainPage.qml | 2 +- nymea-app/ui/components/ColorIcon.qml | 13 +- nymea-app/ui/components/MainPageTile.qml | 2 +- nymea-app/ui/components/MediaPlayer.qml | 1 + nymea-app/ui/components/NymeaToolTip.qml | 2 +- nymea-app/ui/mainviews/EnergyView.qml | 2 +- .../ui/mainviews/energy/ConsumersBarChart.qml | 165 ++++++++++++++++++ .../ui/mainviews/energy/ConsumersPieChart.qml | 1 - .../CurrentConsumptionBalancePieChart.qml | 1 - .../CurrentProductionBalancePieChart.qml | 1 - .../energy/PowerConsumptionBalanceHistory.qml | 2 +- nymea-app/ui/shaders/coloricon.frag | 19 ++ nymea-app/ui/shaders/coloricon.frag.qsb | Bin 0 -> 1741 bytes 108 files changed, 859 insertions(+), 494 deletions(-) create mode 100644 libnymea-app/models/nymeahostsfiltermodel.cpp create mode 100644 libnymea-app/models/nymeahostsfiltermodel.h create mode 100644 nymea-app/ui/mainviews/energy/ConsumersBarChart.qml create mode 100644 nymea-app/ui/shaders/coloricon.frag create mode 100644 nymea-app/ui/shaders/coloricon.frag.qsb diff --git a/libnymea-app/appdata.cpp b/libnymea-app/appdata.cpp index f8d66063..182afb4e 100644 --- a/libnymea-app/appdata.cpp +++ b/libnymea-app/appdata.cpp @@ -115,7 +115,7 @@ void AppData::load() for (int i = metaObject()->propertyOffset(); i < metaObject()->propertyCount(); i++) { QMetaProperty prop = metaObject()->property(i); - qCDebug(dcAppData) << "ComponentComplete property:" << prop.name() << prop.isUser() << prop.type() << prop.isScriptable(this) << prop.isScriptable(); + qCDebug(dcAppData) << "ComponentComplete property:" << prop.name() << prop.isUser() << prop.type() << prop.isScriptable(); QVariantMap params; params.insert("appId", APPLICATION_NAME); if (!m_group.isEmpty()) { diff --git a/libnymea-app/appdata.h b/libnymea-app/appdata.h index 671e8eb5..6630eb5a 100644 --- a/libnymea-app/appdata.h +++ b/libnymea-app/appdata.h @@ -29,7 +29,7 @@ #include #include -class Engine; +#include "engine.h" class AppData : public QObject, public QQmlParserStatus { diff --git a/libnymea-app/configuration/networkmanager.h b/libnymea-app/configuration/networkmanager.h index 1bb5019a..30a63aaa 100644 --- a/libnymea-app/configuration/networkmanager.h +++ b/libnymea-app/configuration/networkmanager.h @@ -28,8 +28,10 @@ #include #include -class Engine; -class NetworkDevices; +#include "engine.h" +#include "types/networkdevices.h" + + class WiredNetworkDevices; class WirelessNetworkDevices; diff --git a/libnymea-app/configuration/nymeaconfiguration.h b/libnymea-app/configuration/nymeaconfiguration.h index c6cba934..7ae0d83f 100644 --- a/libnymea-app/configuration/nymeaconfiguration.h +++ b/libnymea-app/configuration/nymeaconfiguration.h @@ -27,6 +27,9 @@ #include +#include "serverconfigurations.h" +#include "mqttpolicies.h" + class JsonRpcClient; class ServerConfiguration; class ServerConfigurations; @@ -35,7 +38,6 @@ class WebServerConfigurations; class TunnelProxyServerConfiguration; class TunnelProxyServerConfigurations; class MqttPolicy; -class MqttPolicies; class NymeaConfiguration : public QObject { diff --git a/libnymea-app/connection/bluetoothtransport.cpp b/libnymea-app/connection/bluetoothtransport.cpp index dbb370c9..04706667 100644 --- a/libnymea-app/connection/bluetoothtransport.cpp +++ b/libnymea-app/connection/bluetoothtransport.cpp @@ -70,10 +70,10 @@ void BluetoothTransport::disconnect() NymeaTransportInterface::ConnectionState BluetoothTransport::connectionState() const { switch (m_socket->state()) { - case QBluetoothSocket::ConnectedState: + case QBluetoothSocket::SocketState::ConnectedState: return NymeaTransportInterface::ConnectionStateConnected; - case QBluetoothSocket::ConnectingState: - case QBluetoothSocket::ServiceLookupState: + case QBluetoothSocket::SocketState::ConnectingState: + case QBluetoothSocket::SocketState::ServiceLookupState: return NymeaTransportInterface::ConnectionStateConnecting; default: return NymeaTransportInterface::ConnectionStateDisconnected; diff --git a/libnymea-app/connection/discovery/nymeadiscovery.cpp b/libnymea-app/connection/discovery/nymeadiscovery.cpp index 45943f79..d7838a82 100644 --- a/libnymea-app/connection/discovery/nymeadiscovery.cpp +++ b/libnymea-app/connection/discovery/nymeadiscovery.cpp @@ -32,8 +32,8 @@ #include #include #include -#include -#include +//#include +//#include #include "logging.h" NYMEA_LOGGING_CATEGORY(dcDiscovery, "Discovery") @@ -192,7 +192,6 @@ void NymeaDiscovery::setUpnpDiscoveryEnabled(bool upnpDiscoveryEnabled) } } - void NymeaDiscovery::loadFromDisk() { QSettings settings; diff --git a/libnymea-app/connection/discovery/nymeadiscovery.h b/libnymea-app/connection/discovery/nymeadiscovery.h index a710c5c0..f0e13c29 100644 --- a/libnymea-app/connection/discovery/nymeadiscovery.h +++ b/libnymea-app/connection/discovery/nymeadiscovery.h @@ -30,8 +30,8 @@ #include #include "connection/nymeahost.h" +#include "connection/nymeahosts.h" -class NymeaHosts; class UpnpDiscovery; class ZeroconfDiscovery; class BluetoothServiceDiscovery; diff --git a/libnymea-app/connection/discovery/upnpdiscovery.cpp b/libnymea-app/connection/discovery/upnpdiscovery.cpp index 41d4376c..6a682da7 100644 --- a/libnymea-app/connection/discovery/upnpdiscovery.cpp +++ b/libnymea-app/connection/discovery/upnpdiscovery.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +//#include #include "logging.h" @@ -38,16 +38,16 @@ UpnpDiscovery::UpnpDiscovery(NymeaHosts *nymeaHosts, QObject *parent) : QObject(parent), m_nymeaHosts(nymeaHosts) { - m_networkConfigurationManager = new QNetworkConfigurationManager(this); +// m_networkConfigurationManager = new QNetworkConfigurationManager(this); m_networkAccessManager = new QNetworkAccessManager(this); connect(m_networkAccessManager, &QNetworkAccessManager::finished, this, &UpnpDiscovery::networkReplyFinished); m_repeatTimer.setInterval(500); connect(&m_repeatTimer, &QTimer::timeout, this, &UpnpDiscovery::writeDiscoveryPacket); - connect(m_networkConfigurationManager, &QNetworkConfigurationManager::configurationAdded, this, &UpnpDiscovery::updateInterfaces); - connect(m_networkConfigurationManager, &QNetworkConfigurationManager::configurationChanged, this, &UpnpDiscovery::updateInterfaces); - connect(m_networkConfigurationManager, &QNetworkConfigurationManager::configurationRemoved, this, &UpnpDiscovery::updateInterfaces); +// connect(m_networkConfigurationManager, &QNetworkConfigurationManager::configurationAdded, this, &UpnpDiscovery::updateInterfaces); +// connect(m_networkConfigurationManager, &QNetworkConfigurationManager::configurationChanged, this, &UpnpDiscovery::updateInterfaces); +// connect(m_networkConfigurationManager, &QNetworkConfigurationManager::configurationRemoved, this, &UpnpDiscovery::updateInterfaces); updateInterfaces(); } @@ -259,14 +259,14 @@ void UpnpDiscovery::networkReplyFinished(QNetworkReply *reply) } } - if (xml.name() == "friendlyName") { + if (xml.name() == QStringLiteral("friendlyName")) { name = xml.readElementText(); } - if (xml.name() == "modelNumber") { + if (xml.name() == QStringLiteral("modelNumber")) { version = xml.readElementText(); } - if (xml.name() == "UDN") { - uuid = xml.readElementText().split(':').last(); + if (xml.name() == QStringLiteral("UDN")) { + uuid = QUuid(xml.readElementText().split(':').last()); } } } diff --git a/libnymea-app/connection/discovery/upnpdiscovery.h b/libnymea-app/connection/discovery/upnpdiscovery.h index b05bd9aa..3e3dbf34 100644 --- a/libnymea-app/connection/discovery/upnpdiscovery.h +++ b/libnymea-app/connection/discovery/upnpdiscovery.h @@ -29,7 +29,7 @@ #include #include #include -#include +//#include #include #include "../nymeahost.h" @@ -63,7 +63,7 @@ private slots: private: QHash m_sockets; QNetworkAccessManager *m_networkAccessManager; - QNetworkConfigurationManager *m_networkConfigurationManager; +// QNetworkConfigurationManager *m_networkConfigurationManager; QTimer m_repeatTimer; diff --git a/libnymea-app/connection/discovery/zeroconfdiscovery.cpp b/libnymea-app/connection/discovery/zeroconfdiscovery.cpp index 202ffbd0..7633ef75 100644 --- a/libnymea-app/connection/discovery/zeroconfdiscovery.cpp +++ b/libnymea-app/connection/discovery/zeroconfdiscovery.cpp @@ -108,7 +108,7 @@ void ZeroconfDiscovery::serviceEntryAdded(const QZeroConfService &entry) qCDebug(dcZeroConf()) << "Service discovered" << entry->type() << entry->name() << " IP:" << entry->ip().toString() << entry->txt(); - QString uuid; + QUuid uuid; bool sslEnabled = false; QString serverName; QString version; @@ -118,7 +118,7 @@ void ZeroconfDiscovery::serviceEntryAdded(const QZeroConfService &entry) sslEnabled = (txtRecord.second == "true"); } if (txtRecord.first == "uuid") { - uuid = txtRecord.second; + uuid = QUuid(txtRecord.second); } if (txtRecord.first == "name") { serverName = txtRecord.second; @@ -167,7 +167,7 @@ void ZeroconfDiscovery::serviceEntryRemoved(const QZeroConfService &entry) return; } - QString uuid; + QUuid uuid; bool sslEnabled = false; QString serverName; QString version; @@ -177,7 +177,7 @@ void ZeroconfDiscovery::serviceEntryRemoved(const QZeroConfService &entry) sslEnabled = (txtRecord.second == "true"); } if (txtRecord.first == "uuid") { - uuid = txtRecord.second; + uuid = QUuid(txtRecord.second); } if (txtRecord.first == "name") { serverName = txtRecord.second; diff --git a/libnymea-app/connection/nymeaconnection.cpp b/libnymea-app/connection/nymeaconnection.cpp index c0a58997..84f3e53c 100644 --- a/libnymea-app/connection/nymeaconnection.cpp +++ b/libnymea-app/connection/nymeaconnection.cpp @@ -45,21 +45,18 @@ NYMEA_LOGGING_CATEGORY(dcNymeaConnection, "NymeaConnection") NymeaConnection::NymeaConnection(QObject *parent) : QObject(parent) { - m_networkReachabilityMonitor = new NetworkReachabilityMonitor(this); - connect(m_networkReachabilityMonitor, &NetworkReachabilityMonitor::availableBearerTypesChanged, this, &NymeaConnection::availableBearerTypesChanged); - connect(m_networkReachabilityMonitor, &NetworkReachabilityMonitor::availableBearerTypesUpdated, this, &NymeaConnection::onAvailableBearerTypesUpdated); +// m_networkConfigManager = new QNetworkConfigurationManager(this); -#ifdef Q_OS_IOS - connect(m_networkReachabilityMonitor, &NetworkReachabilityMonitor::availableBearerTypesChanged, this, [this](){ - if (m_currentTransport) { - qCInfo(dcNymeaConnection()) << "Available bearer types changed:" << m_networkReachabilityMonitor->availableBearerTypes() << "currently used:" << m_usedBearerType; - if (!m_networkReachabilityMonitor->availableBearerTypes().testFlag(m_usedBearerType)) { - qCInfo(dcNymeaConnection()) << "Used bearer type" << m_usedBearerType << "isn't available any more. Reconnecting."; - m_currentTransport->disconnect(); - } - } - }); -#endif +// QObject::connect(m_networkConfigManager, &QNetworkConfigurationManager::configurationAdded, this, [this](const QNetworkConfiguration &config){ +// Q_UNUSED(config) +// qCDebug(dcNymeaConnection()) << "Network configuration added:" << config.name() << config.bearerTypeName() << config.purpose(); +// updateActiveBearers(); +// }); +// QObject::connect(m_networkConfigManager, &QNetworkConfigurationManager::configurationRemoved, this, [this](const QNetworkConfiguration &config){ +// Q_UNUSED(config) +// qCDebug(dcNymeaConnection()) << "Network configuration removed:" << config.name() << config.bearerTypeName() << config.purpose(); +// updateActiveBearers(); +// }); QGuiApplication *app = static_cast(QGuiApplication::instance()); QObject::connect(app, &QGuiApplication::applicationStateChanged, this, [app, this](Qt::ApplicationState state) { @@ -398,6 +395,39 @@ void NymeaConnection::onDataAvailable(const QByteArray &data) void NymeaConnection::onAvailableBearerTypesUpdated() { + NymeaConnection::BearerTypes availableBearerTypes; +// QList configs = m_networkConfigManager->allConfigurations(QNetworkConfiguration::Active); +// qCDebug(dcNymeaConnection()) << "Network configuations:" << configs.count(); +// foreach (const QNetworkConfiguration &config, configs) { +// qCDebug(dcNymeaConnection()) << "Active network config:" << config.name() << config.bearerTypeFamily() << config.bearerTypeName(); + +// // NOTE: iOS doesn't correctly report bearer types. It'll be Unknown all the time. Let's hardcode it to WiFi for that... +//#if defined(Q_OS_IOS) + availableBearerTypes.setFlag(NymeaConnection::BearerTypeWiFi); +//#else +// availableBearerTypes.setFlag(qBearerTypeToNymeaBearerType(config.bearerType())); +//#endif +// } +// if (availableBearerTypes == NymeaConnection::BearerTypeNone) { +// // This is just debug info... On some platform bearer management seems a bit broken, so let's get some infos right away... +// qCDebug(dcNymeaConnection()) << "No active bearer available. Inactive bearers are:"; +// QList configs = m_networkConfigManager->allConfigurations(); +// foreach (const QNetworkConfiguration &config, configs) { +// qCDebug(dcNymeaConnection()) << "Inactive network config:" << config.name() << config.bearerTypeFamily() << config.bearerTypeName(); +// } + +// qCDebug(dcNymeaConnection()) << "Updating network manager"; +// m_networkConfigManager->updateConfigurations(); +// } + + if (m_availableBearerTypes != availableBearerTypes) { + qCInfo(dcNymeaConnection()) << "Available Bearer Types changed to:" << availableBearerTypes; + m_availableBearerTypes = availableBearerTypes; + emit availableBearerTypesChanged(); + } else { + qCDebug(dcNymeaConnection()) << "Available Bearer Types:" << availableBearerTypes; + } + if (!m_currentHost) { // No host set... Nothing to do... qCInfo(dcNymeaConnection()) << "No current host... Nothing to do..."; @@ -524,6 +554,33 @@ bool NymeaConnection::connectInternal(Connection *connection) return newTransport->connect(connection->url()); } +//NymeaConnection::BearerType NymeaConnection::qBearerTypeToNymeaBearerType(QNetworkConfiguration::BearerType type) const +//{ +// switch (type) { +// case QNetworkConfiguration::BearerUnknown: +// // Unable to determine the connection type. Assume it's something we can establish any connection type on +// return BearerTypeAll; +// case QNetworkConfiguration::BearerEthernet: +// return BearerTypeEthernet; +// case QNetworkConfiguration::BearerWLAN: +// return BearerTypeWiFi; +// case QNetworkConfiguration::Bearer2G: +// case QNetworkConfiguration::BearerCDMA2000: +// case QNetworkConfiguration::BearerWCDMA: +// case QNetworkConfiguration::BearerHSPA: +// case QNetworkConfiguration::BearerWiMAX: +// case QNetworkConfiguration::BearerEVDO: +// case QNetworkConfiguration::BearerLTE: +// case QNetworkConfiguration::Bearer3G: +// case QNetworkConfiguration::Bearer4G: +// return BearerTypeMobileData; +// case QNetworkConfiguration::BearerBluetooth: +// // Note: Do not confuse this with the Bluetooth transport... For Qt, this means IP over BT, not RFCOMM as we do it. +// return BearerTypeNone; +// } +// return BearerTypeAll; +//} + bool NymeaConnection::isConnectionBearerAvailable(Connection::BearerType connectionBearerType) const { switch (connectionBearerType) { diff --git a/libnymea-app/connection/nymeaconnection.h b/libnymea-app/connection/nymeaconnection.h index f805c25f..9a19269c 100644 --- a/libnymea-app/connection/nymeaconnection.h +++ b/libnymea-app/connection/nymeaconnection.h @@ -30,7 +30,7 @@ #include #include #include -#include +//#include #include #include "nymeahost.h" @@ -125,7 +125,8 @@ private: private: ConnectionStatus m_connectionStatus = ConnectionStatusUnconnected; - NetworkReachabilityMonitor *m_networkReachabilityMonitor = nullptr; +// QNetworkConfigurationManager *m_networkConfigManager = nullptr; + NymeaConnection::BearerTypes m_availableBearerTypes = BearerTypeNone; QHash m_transportFactories; QHash m_transportCandidates; diff --git a/libnymea-app/connection/nymeahosts.cpp b/libnymea-app/connection/nymeahosts.cpp index 45e11a17..fcf33920 100644 --- a/libnymea-app/connection/nymeahosts.cpp +++ b/libnymea-app/connection/nymeahosts.cpp @@ -162,138 +162,3 @@ QHash NymeaHosts::roleNames() const roles[VersionRole] = "version"; return roles; } - -NymeaHostsFilterModel::NymeaHostsFilterModel(QObject *parent): - QSortFilterProxyModel(parent) -{ - -} - -NymeaDiscovery *NymeaHostsFilterModel::discovery() const -{ - return m_nymeaDiscovery; -} - -void NymeaHostsFilterModel::setDiscovery(NymeaDiscovery *discovery) -{ - if (m_nymeaDiscovery != discovery) { - m_nymeaDiscovery = discovery; - setSourceModel(discovery->nymeaHosts()); - emit discoveryChanged(); - - connect(discovery->nymeaHosts(), &NymeaHosts::hostChanged, this, [this](){ -// qDebug() << "Host Changed!"; - invalidateFilter(); - emit countChanged(); - }); - - emit countChanged(); - } -} - -JsonRpcClient *NymeaHostsFilterModel::jsonRpcClient() const -{ - return m_jsonRpcClient; -} - -void NymeaHostsFilterModel::setJsonRpcClient(JsonRpcClient *jsonRpcClient) -{ - if (m_jsonRpcClient != jsonRpcClient) { - m_jsonRpcClient = jsonRpcClient; - emit jsonRpcClientChanged(); - - connect(m_jsonRpcClient, &JsonRpcClient::availableBearerTypesChanged, this, [this](){ -// qDebug() << "Bearer Types Changed!"; - invalidateFilter(); - emit countChanged(); - }); - - invalidateFilter(); - emit countChanged(); - } -} - -bool NymeaHostsFilterModel::showUnreachableBearers() const -{ - return m_showUneachableBearers; -} - -void NymeaHostsFilterModel::setShowUnreachableBearers(bool showUnreachableBearers) -{ - if (m_showUneachableBearers != showUnreachableBearers) { - m_showUneachableBearers = showUnreachableBearers; - emit showUnreachableBearersChanged(); - invalidateFilter(); - emit countChanged(); - } -} - -bool NymeaHostsFilterModel::showUnreachableHosts() const -{ - return m_showUneachableHosts; -} - -void NymeaHostsFilterModel::setShowUnreachableHosts(bool showUnreachableHosts) -{ - if (m_showUneachableHosts != showUnreachableHosts) { - m_showUneachableHosts = showUnreachableHosts; - emit showUnreachableHostsChanged(); - invalidateFilter(); - emit countChanged(); - } -} - -NymeaHost *NymeaHostsFilterModel::get(int index) const -{ - return m_nymeaDiscovery->nymeaHosts()->get(mapToSource(this->index(index, 0)).row()); -} - -bool NymeaHostsFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const -{ - Q_UNUSED(sourceParent) - NymeaHost *host = m_nymeaDiscovery->nymeaHosts()->get(sourceRow); - if (m_jsonRpcClient && !m_showUneachableBearers) { - bool hasReachableConnection = false; - for (int i = 0; i < host->connections()->rowCount(); i++) { -// qCritical() << "checking host for available bearer" << host->name() << host->connections()->get(i)->url() << "available bearer types:" << m_jsonRpcClient->availableBearerTypes() << "hosts bearer types" << host->connections()->get(i)->bearerType(); - // Either enable a connection when the Bearer type is directly available - switch (host->connections()->get(i)->bearerType()) { - case Connection::BearerTypeLan: - hasReachableConnection |= m_jsonRpcClient->availableBearerTypes().testFlag(NymeaConnection::BearerTypeEthernet); - hasReachableConnection |= m_jsonRpcClient->availableBearerTypes().testFlag(NymeaConnection::BearerTypeWiFi); - break; - case Connection::BearerTypeWan: - case Connection::BearerTypeCloud: - hasReachableConnection |= m_jsonRpcClient->availableBearerTypes().testFlag(NymeaConnection::BearerTypeEthernet); - hasReachableConnection |= m_jsonRpcClient->availableBearerTypes().testFlag(NymeaConnection::BearerTypeWiFi); - hasReachableConnection |= m_jsonRpcClient->availableBearerTypes().testFlag(NymeaConnection::BearerTypeMobileData); - break; - case Connection::BearerTypeBluetooth: - hasReachableConnection |= m_jsonRpcClient->availableBearerTypes().testFlag(NymeaConnection::BearerTypeBluetooth); - break; - case Connection::BearerTypeUnknown: - case Connection::BearerTypeLoopback: - hasReachableConnection = true; - break; - case Connection::BearerTypeNone: - break; - } - } - if (!hasReachableConnection) { - return false; - } - } - if (!m_showUneachableHosts) { - bool isOnline = false; - for (int i = 0; i < host->connections()->rowCount(); i++) { - if (host->connections()->get(i)->online()) { - isOnline = true; - break; - } - } - if (!isOnline) { - return false; - } - } - return true; -} diff --git a/libnymea-app/connection/nymeahosts.h b/libnymea-app/connection/nymeahosts.h index 725048bb..1ebdb15f 100644 --- a/libnymea-app/connection/nymeahosts.h +++ b/libnymea-app/connection/nymeahosts.h @@ -30,8 +30,6 @@ #include #include #include "nymeahost.h" - -class NymeaDiscovery; class JsonRpcClient; class NymeaHosts : public QAbstractListModel diff --git a/libnymea-app/connection/nymeatransportinterface.h b/libnymea-app/connection/nymeatransportinterface.h index 801bced5..980fd1b6 100644 --- a/libnymea-app/connection/nymeatransportinterface.h +++ b/libnymea-app/connection/nymeatransportinterface.h @@ -28,6 +28,7 @@ #include #include #include +#include class NymeaTransportInterface; diff --git a/libnymea-app/connection/tcpsockettransport.cpp b/libnymea-app/connection/tcpsockettransport.cpp index b7e8b13d..92346ec3 100644 --- a/libnymea-app/connection/tcpsockettransport.cpp +++ b/libnymea-app/connection/tcpsockettransport.cpp @@ -38,8 +38,7 @@ TcpSocketTransport::TcpSocketTransport(QObject *parent) : NymeaTransportInterfac typedef void (QSslSocket:: *sslErrorsSignal)(const QList &); QObject::connect(&m_socket, static_cast(&QSslSocket::sslErrors), this, &TcpSocketTransport::sslErrors); QObject::connect(&m_socket, &QSslSocket::readyRead, this, &TcpSocketTransport::socketReadyRead); - typedef void (QSslSocket:: *errorSignal)(QAbstractSocket::SocketError); - QObject::connect(&m_socket, static_cast(&QSslSocket::error), this, &TcpSocketTransport::error); + QObject::connect(&m_socket, &QSslSocket::errorOccurred, this, &TcpSocketTransport::error); QObject::connect(&m_socket, &QSslSocket::stateChanged, this, &TcpSocketTransport::onSocketStateChanged); } diff --git a/libnymea-app/energy/energymanager.h b/libnymea-app/energy/energymanager.h index cbeda3ad..3366a85f 100644 --- a/libnymea-app/energy/energymanager.h +++ b/libnymea-app/energy/energymanager.h @@ -28,7 +28,7 @@ #include #include -class Engine; +#include "engine.h" class EnergyManager : public QObject { diff --git a/libnymea-app/engine.cpp b/libnymea-app/engine.cpp index 1d42b9aa..10bb3b6a 100644 --- a/libnymea-app/engine.cpp +++ b/libnymea-app/engine.cpp @@ -49,7 +49,19 @@ Engine::Engine(QObject *parent) : connect(m_thingManager, &ThingManager::fetchingDataChanged, this, &Engine::onThingManagerFetchingChanged); connect(m_jsonRpcClient, &JsonRpcClient::connectedChanged, this, [this]() { - qDebug() << "JSONRpc connected changed:" << m_jsonRpcClient->connected(); + qDebug() << "JSONRpc connected changed:" << m_jsonRpcClient->connected() << "AWS status:" << AWSClient::instance()->awsDevices()->rowCount(); + if (m_jsonRpcClient->connected() && m_jsonRpcClient->cloudConnectionState() == JsonRpcClient::CloudConnectionStateConnected) { + if (AWSClient::instance()->awsDevices()->getDevice(m_jsonRpcClient->serverUuid().toString()) == nullptr) { + m_jsonRpcClient->setupRemoteAccess(AWSClient::instance()->idToken(), AWSClient::instance()->userId()); + } + } + }); + connect(m_jsonRpcClient, &JsonRpcClient::cloudConnectionStateChanged, this, [this](){ + if (m_jsonRpcClient->connected() && m_jsonRpcClient->cloudConnectionState() == JsonRpcClient::CloudConnectionStateConnected) { + if (AWSClient::instance()->awsDevices()->getDevice(m_jsonRpcClient->serverUuid().toString()) == nullptr) { + m_jsonRpcClient->setupRemoteAccess(AWSClient::instance()->idToken(), AWSClient::instance()->userId()); + } + } }); } @@ -93,6 +105,22 @@ SystemController *Engine::systemController() const return m_systemController; } +void Engine::deployCertificate() +{ + if (!m_jsonRpcClient->connected()) { + qWarning() << "JSONRPC not connected. Cannot deploy certificate"; + return; + } + if (!AWSClient::instance()->isLoggedIn()) { + qWarning() << "Not logged in at AWS. Cannot deploy certificate"; + return; + } + AWSClient::instance()->fetchCertificate(m_jsonRpcClient->serverUuid().toString(), [this](const QByteArray &rootCA, const QByteArray &certificate, const QByteArray &publicKey, const QByteArray &privateKey, const QString &endpoint){ + qDebug() << "Certificate received" << certificate << publicKey << privateKey; + m_jsonRpcClient->deployCertificate(rootCA, certificate, publicKey, privateKey, endpoint); + }); +} + void Engine::onConnectedChanged() { qDebug() << "Engine: connected changed:" << m_jsonRpcClient->connected(); diff --git a/libnymea-app/engine.h b/libnymea-app/engine.h index ce0a4b22..6f551c46 100644 --- a/libnymea-app/engine.h +++ b/libnymea-app/engine.h @@ -31,13 +31,12 @@ #include "connection/nymeatransportinterface.h" #include "jsonrpc/jsonrpcclient.h" -class RuleManager; -class ScriptManager; -class LogManager; -class TagsManager; -class NymeaConfiguration; -class SystemController; -class NetworkManager; +#include "rulemanager.h" +#include "scriptmanager.h" +#include "logmanager.h" +#include "tagsmanager.h" +#include "configuration/nymeaconfiguration.h" +#include "system/systemcontroller.h" class Engine : public QObject { @@ -78,4 +77,6 @@ private slots: }; +Q_DECLARE_METATYPE(Engine*) + #endif // ENGINE_H diff --git a/libnymea-app/interfacesmodel.h b/libnymea-app/interfacesmodel.h index fe2a6f8e..cd7d20e3 100644 --- a/libnymea-app/interfacesmodel.h +++ b/libnymea-app/interfacesmodel.h @@ -29,9 +29,8 @@ #include #include "things.h" - -class Engine; -class ThingsProxy; +#include "engine.h" +#include "thingsproxy.h" class InterfacesModel : public QAbstractListModel { diff --git a/libnymea-app/jsonrpc/jsonrpcclient.cpp b/libnymea-app/jsonrpc/jsonrpcclient.cpp index b50efae8..9dcbf913 100644 --- a/libnymea-app/jsonrpc/jsonrpcclient.cpp +++ b/libnymea-app/jsonrpc/jsonrpcclient.cpp @@ -153,7 +153,7 @@ void JsonRpcClient::disconnectFromHost() m_connection->disconnectFromHost(); } -void JsonRpcClient::acceptCertificate(const QString &serverUuid, const QByteArray &pem) +void JsonRpcClient::acceptCertificate(const QUuid &serverUuid, const QByteArray &pem) { qDebug() << "Pinning new certificate for" << serverUuid << pem; storePem(serverUuid, pem); @@ -199,7 +199,7 @@ void JsonRpcClient::notificationReceived(const QVariantMap &data) m_token = data.value("params").toMap().value("token").toByteArray(); QSettings settings; settings.beginGroup("jsonTokens"); - settings.setValue(m_connection->currentHost()->uuid().toString(), m_token); + settings.setValue(m_serverUuid.toString(), m_token); settings.endGroup(); m_initialSetupRequired = false; @@ -305,7 +305,7 @@ QString JsonRpcClient::jsonRpcVersion() const return m_jsonRpcVersion.toString(); } -QString JsonRpcClient::serverUuid() const +QUuid JsonRpcClient::serverUuid() const { return m_connection && m_connection->currentHost() ? m_connection->currentHost()->uuid().toString() : ""; } @@ -394,7 +394,7 @@ void JsonRpcClient::processAuthenticate(int /*commandId*/, const QVariantMap &da emit permissionsChanged(); QSettings settings; settings.beginGroup("jsonTokens"); - settings.setValue(m_connection->currentHost()->uuid().toString(), m_token); + settings.setValue(m_serverUuid.toString(), m_token); settings.endGroup(); emit authenticationRequiredChanged(); @@ -481,8 +481,8 @@ void JsonRpcClient::sendRequest(const QVariantMap &request) bool JsonRpcClient::loadPem(const QUuid &serverUud, QByteArray &pem) { - QDir dir(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/sslcerts/"); - QFile certFile(dir.absoluteFilePath(serverUud.toString().remove(QRegExp("[{}]")) + ".pem")); + QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/sslcerts/"); + QFile certFile(dir.absoluteFilePath(serverUud.toString().remove(QRegularExpression("[{}]")) + ".pem")); if (!certFile.open(QFile::ReadOnly)) { return false; } @@ -493,11 +493,11 @@ bool JsonRpcClient::loadPem(const QUuid &serverUud, QByteArray &pem) bool JsonRpcClient::storePem(const QUuid &serverUuid, const QByteArray &pem) { - QDir dir(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/sslcerts/"); + QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/sslcerts/"); if (!dir.exists()) { - dir.mkpath(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/sslcerts/"); + dir.mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/sslcerts/"); } - QFile certFile(dir.absoluteFilePath(serverUuid.toString().remove(QRegExp("[{}]")) + ".pem")); + QFile certFile(dir.absoluteFilePath(serverUuid.toString().remove(QRegularExpression("[{}]")) + ".pem")); if (!certFile.open(QFile::WriteOnly | QFile::Truncate)) { return false; } @@ -600,7 +600,7 @@ void JsonRpcClient::dataReceived(const QByteArray &data) m_token.clear(); QSettings settings; settings.beginGroup("jsonTokens"); - settings.setValue(serverUuid(), m_token); + settings.setValue(m_serverUuid.toString(), m_token); settings.endGroup(); emit authenticationRequiredChanged(); m_authenticated = false; @@ -651,6 +651,7 @@ void JsonRpcClient::helloReply(int /*commandId*/, const QVariantMap ¶ms) m_pushButtonAuthAvailable = params.value("pushButtonAuthAvailable").toBool(); emit pushButtonAuthAvailableChanged(); + m_serverUuid = params.value("uuid").toUuid(); m_serverVersion = params.value("version").toString(); QUuid serverUuid = params.value("uuid").toUuid(); QString name = params.value("name").toString(); @@ -721,7 +722,7 @@ void JsonRpcClient::helloReply(int /*commandId*/, const QVariantMap ¶ms) // Reject the connection until the UI explicitly accepts this... m_connection->disconnectFromHost(); - emit verifyConnectionCertificate(serverUuid.toString(), issuerInfo, certificate.toPem()); + emit verifyConnectionCertificate(m_serverUuid.toString(), issuerInfo, certificate.toPem()); return; } qCInfo(dcJsonRpc()) << "This connections certificate is trusted."; @@ -769,7 +770,7 @@ void JsonRpcClient::helloReply(int /*commandId*/, const QVariantMap ¶ms) // Reload the token, now that we're certain about the server uuid. QSettings settings; settings.beginGroup("jsonTokens"); - m_token = settings.value(serverUuid.toString()).toByteArray(); + m_token = settings.value(m_serverUuid.toString()).toByteArray(); settings.endGroup(); emit authenticationRequiredChanged(); diff --git a/libnymea-app/jsonrpc/jsonrpcclient.h b/libnymea-app/jsonrpc/jsonrpcclient.h index 4b9fbf9e..9cd4cabd 100644 --- a/libnymea-app/jsonrpc/jsonrpcclient.h +++ b/libnymea-app/jsonrpc/jsonrpcclient.h @@ -51,7 +51,7 @@ class JsonRpcClient : public QObject Q_PROPERTY(bool authenticated READ authenticated NOTIFY authenticatedChanged) Q_PROPERTY(QString serverVersion READ serverVersion NOTIFY handshakeReceived) Q_PROPERTY(QString jsonRpcVersion READ jsonRpcVersion NOTIFY handshakeReceived) - Q_PROPERTY(QString serverUuid READ serverUuid NOTIFY handshakeReceived) + Q_PROPERTY(QUuid serverUuid READ serverUuid NOTIFY handshakeReceived) Q_PROPERTY(QString serverName READ serverName NOTIFY serverNameChanged) Q_PROPERTY(QString serverQtVersion READ serverQtVersion NOTIFY serverQtVersionChanged) Q_PROPERTY(QString serverQtBuildVersion READ serverQtBuildVersion NOTIFY serverQtVersionChanged) @@ -85,7 +85,7 @@ public: QString serverVersion() const; QString jsonRpcVersion() const; - QString serverUuid() const; + QUuid serverUuid() const; QString serverName() const; QString serverQtVersion(); QString serverQtBuildVersion(); @@ -94,7 +94,7 @@ public: // ui methods Q_INVOKABLE void connectToHost(NymeaHost *host, Connection *connection = nullptr); Q_INVOKABLE void disconnectFromHost(); - Q_INVOKABLE void acceptCertificate(const QString &serverUuid, const QByteArray &pem); + Q_INVOKABLE void acceptCertificate(const QUuid &serverUuid, const QByteArray &pem); Q_INVOKABLE bool tokenExists(const QString &serverUuid) const; Q_INVOKABLE void addToken(const QString &serverUuid, const QByteArray &token); @@ -154,6 +154,7 @@ private: bool m_pushButtonAuthAvailable = false; bool m_authenticated = false; int m_pendingPushButtonTransaction = -1; + QUuid m_serverUuid; QVersionNumber m_jsonRpcVersion; QString m_serverVersion; QString m_serverQtVersion; diff --git a/libnymea-app/libnymea-app-core.h b/libnymea-app/libnymea-app-core.h index 64761ecc..cbc0ae1f 100644 --- a/libnymea-app/libnymea-app-core.h +++ b/libnymea-app/libnymea-app-core.h @@ -28,6 +28,7 @@ #include "engine.h" #include "connection/nymeahosts.h" #include "connection/nymeahost.h" +#include "models/nymeahostsfiltermodel.h" #include "connection/discovery/nymeadiscovery.h" #include "vendorsproxy.h" #include "thingclassesproxy.h" diff --git a/libnymea-app/libnymea-app.pri b/libnymea-app/libnymea-app.pri index f293f761..72ff5352 100644 --- a/libnymea-app/libnymea-app.pri +++ b/libnymea-app/libnymea-app.pri @@ -30,6 +30,7 @@ SOURCES += \ $$PWD/models/boolseriesadapter.cpp \ $$PWD/models/newlogentry.cpp \ $$PWD/models/newlogsmodel.cpp \ + $$PWD/models/nymeahostsfiltermodel.cpp \ $$PWD/models/scriptsproxymodel.cpp \ $$PWD/pluginconfigmanager.cpp \ $$PWD/serverdebug/serverdebugmanager.cpp \ @@ -199,6 +200,7 @@ HEADERS += \ $$PWD/models/boolseriesadapter.h \ $$PWD/models/newlogentry.h \ $$PWD/models/newlogsmodel.h \ + $$PWD/models/nymeahostsfiltermodel.h \ $$PWD/models/scriptsproxymodel.h \ $$PWD/pluginconfigmanager.h \ $$PWD/serverdebug/serverdebugmanager.h \ diff --git a/libnymea-app/modbus/modbusrtumanager.cpp b/libnymea-app/modbus/modbusrtumanager.cpp index 0ba1246b..aed595ac 100644 --- a/libnymea-app/modbus/modbusrtumanager.cpp +++ b/libnymea-app/modbus/modbusrtumanager.cpp @@ -148,7 +148,7 @@ ModbusRtuMaster *ModbusRtuManager::unpackModbusRtuMaster(const QVariantMap &modb void ModbusRtuManager::notificationReceived(const QVariantMap ¬ification) { QString notificationString = notification.value("notification").toString(); - qDebug() << "Received notification" << notificationString << endl << notification; + qDebug() << "Received notification" << notificationString << Qt::endl << notification; if (notificationString == "ModbusRtu.SerialPortAdded") { QVariantMap serialPortMap = notification.value("params").toMap().value("serialPort").toMap(); m_serialPorts->addSerialPort(SerialPort::unpackSerialPort(serialPortMap, m_serialPorts)); diff --git a/libnymea-app/modbus/modbusrtumanager.h b/libnymea-app/modbus/modbusrtumanager.h index 637a98df..4e64e8d9 100644 --- a/libnymea-app/modbus/modbusrtumanager.h +++ b/libnymea-app/modbus/modbusrtumanager.h @@ -29,10 +29,10 @@ #include "types/serialports.h" -class Engine; -class JsonRpcClient; +#include "engine.h" +#include "modbusrtumasters.h" + class ModbusRtuMaster; -class ModbusRtuMasters; class ModbusRtuManager : public QObject { diff --git a/libnymea-app/models/barseriesadapter.cpp b/libnymea-app/models/barseriesadapter.cpp index d7a6e17d..801e7b78 100644 --- a/libnymea-app/models/barseriesadapter.cpp +++ b/libnymea-app/models/barseriesadapter.cpp @@ -46,12 +46,12 @@ void BarSeriesAdapter::setLogsModel(LogsModel *logsModel) } } -QtCharts::QAbstractBarSeries *BarSeriesAdapter::barSeries() const +QAbstractBarSeries *BarSeriesAdapter::barSeries() const { return m_barSeries; } -void BarSeriesAdapter::setBarSeries(QtCharts::QAbstractBarSeries *barSeries) +void BarSeriesAdapter::setBarSeries(QAbstractBarSeries *barSeries) { if (m_barSeries != barSeries) { m_barSeries = barSeries; @@ -78,7 +78,7 @@ void BarSeriesAdapter::update() if (!m_barSeries || !m_logsModel) { return; } - m_set = new QtCharts::QBarSet(m_barSeries->name()); + m_set = new QBarSet(m_barSeries->name()); m_barSeries->append(m_set); for (int i = 0; i < m_logsModel->rowCount(); i++) { diff --git a/libnymea-app/models/barseriesadapter.h b/libnymea-app/models/barseriesadapter.h index 18ee35bf..dd9027eb 100644 --- a/libnymea-app/models/barseriesadapter.h +++ b/libnymea-app/models/barseriesadapter.h @@ -31,11 +31,15 @@ #include #include +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +using namespace QtCharts; +#endif + class BarSeriesAdapter : public QObject { Q_OBJECT Q_PROPERTY(LogsModel* logsModel READ logsModel WRITE setLogsModel NOTIFY logsModelChanged) - Q_PROPERTY(QtCharts::QAbstractBarSeries* barSeries READ barSeries WRITE setBarSeries NOTIFY barSeriesChanged) + Q_PROPERTY(QAbstractBarSeries* barSeries READ barSeries WRITE setBarSeries NOTIFY barSeriesChanged) Q_PROPERTY(Interval interval READ interval WRITE setInterval NOTIFY intervalChanged) @@ -52,8 +56,8 @@ public: LogsModel *logsModel() const; void setLogsModel(LogsModel *logsModel); - QtCharts::QAbstractBarSeries *barSeries() const; - void setBarSeries(QtCharts::QAbstractBarSeries *barSeries); + QAbstractBarSeries *barSeries() const; + void setBarSeries(QAbstractBarSeries *barSeries); Interval interval() const; void setInterval(Interval interval); @@ -80,8 +84,8 @@ private: }; LogsModel *m_logsModel = nullptr; - QtCharts::QAbstractBarSeries *m_barSeries = nullptr; - QtCharts::QBarSet *m_set = nullptr; + QAbstractBarSeries *m_barSeries = nullptr; + QBarSet *m_set = nullptr; Interval m_interval = IntervalMinutes; QList m_timeslots; diff --git a/libnymea-app/models/interfacesproxy.h b/libnymea-app/models/interfacesproxy.h index 1ee4f3af..559d6474 100644 --- a/libnymea-app/models/interfacesproxy.h +++ b/libnymea-app/models/interfacesproxy.h @@ -27,8 +27,8 @@ #include -class Things; -class ThingsProxy; +#include "things.h" +#include "thingsproxy.h" class Interface; class Interfaces; diff --git a/libnymea-app/models/logsmodel.cpp b/libnymea-app/models/logsmodel.cpp index 26232259..5e017103 100644 --- a/libnymea-app/models/logsmodel.cpp +++ b/libnymea-app/models/logsmodel.cpp @@ -312,8 +312,8 @@ void LogsModel::logsReply(int /*commandId*/, const QVariantMap &data) foreach (const QVariant &logEntryVariant, logEntries) { QVariantMap entryMap = logEntryVariant.toMap(); QDateTime timeStamp = QDateTime::fromMSecsSinceEpoch(entryMap.value("timestamp").toLongLong()); - QString thingId = entryMap.value("thingId").toString(); - QString typeId = entryMap.value("typeId").toString(); + QUuid thingId = entryMap.value("thingId").toUuid(); + QUuid typeId = entryMap.value("typeId").toUuid(); QMetaEnum sourceEnum = QMetaEnum::fromType(); LogEntry::LoggingSource loggingSource = static_cast(sourceEnum.keyToValue(entryMap.value("source").toByteArray())); QMetaEnum loggingEventTypeEnum = QMetaEnum::fromType(); diff --git a/libnymea-app/models/logsmodel.h b/libnymea-app/models/logsmodel.h index 2f9495fa..d3180820 100644 --- a/libnymea-app/models/logsmodel.h +++ b/libnymea-app/models/logsmodel.h @@ -29,12 +29,11 @@ #include #include "types/logentry.h" +#include "engine.h" #include Q_DECLARE_LOGGING_CATEGORY(dcLogEngine) -class Engine; - class LogsModel : public QAbstractListModel, public QQmlParserStatus { Q_OBJECT diff --git a/libnymea-app/models/logsmodelng.cpp b/libnymea-app/models/logsmodelng.cpp index 6723bdec..419015f9 100644 --- a/libnymea-app/models/logsmodelng.cpp +++ b/libnymea-app/models/logsmodelng.cpp @@ -194,12 +194,12 @@ void LogsModelNg::setEndTime(const QDateTime &endTime) } } -QtCharts::QXYSeries *LogsModelNg::graphSeries() const +QXYSeries *LogsModelNg::graphSeries() const { return m_graphSeries; } -void LogsModelNg::setGraphSeries(QtCharts::QXYSeries *graphSeries) +void LogsModelNg::setGraphSeries(QXYSeries *graphSeries) { m_graphSeries = graphSeries; } @@ -315,8 +315,8 @@ void LogsModelNg::logsReply(int commandId, const QVariantMap &data) foreach (const QVariant &logEntryVariant, logEntries) { QVariantMap entryMap = logEntryVariant.toMap(); QDateTime timeStamp = QDateTime::fromMSecsSinceEpoch(entryMap.value("timestamp").toLongLong()); - QString thingId = entryMap.value("thingId").toString(); - QString typeId = entryMap.value("typeId").toString(); + QUuid thingId = entryMap.value("thingId").toUuid(); + QUuid typeId = entryMap.value("typeId").toUuid(); QMetaEnum sourceEnum = QMetaEnum::fromType(); LogEntry::LoggingSource loggingSource = static_cast(sourceEnum.keyToValue(entryMap.value("source").toByteArray())); QMetaEnum loggingEventTypeEnum = QMetaEnum::fromType(); @@ -382,10 +382,10 @@ void LogsModelNg::logsReply(int commandId, const QVariantMap &data) } // Adjust min/max - if (!newMin.isValid() || newMin > entry->value()) { + if (!newMin.isValid() || newMin.toDouble() > entry->value().toDouble()) { newMin = 0; } - if (!newMax.isValid() || newMax < entry->value()) { + if (!newMax.isValid() || newMax .toDouble() < entry->value().toDouble()) { newMax = 1; } @@ -401,10 +401,10 @@ void LogsModelNg::logsReply(int commandId, const QVariantMap &data) m_graphSeries->append(QPointF(entry->timestamp().toMSecsSinceEpoch(), value.toReal())); // Adjust min/max - if (!newMin.isValid() || newMin > value) { + if (!newMin.isValid() || newMin.toDouble() > value.toDouble()) { newMin = value.toReal(); } - if (!newMax.isValid() || newMax < value) { + if (!newMax.isValid() || newMax.toDouble() < value.toDouble()) { newMax = value.toReal(); } } @@ -566,11 +566,11 @@ void LogsModelNg::newLogEntryReceived(const QVariantMap &data) } - if (m_minValue > entry->value().toReal()) { + if (m_minValue.toReal() > entry->value().toReal()) { m_minValue = entry->value().toReal(); emit minValueChanged(); } - if (m_maxValue < entry->value().toReal()) { + if (m_maxValue.toReal() < entry->value().toReal()) { m_maxValue = entry->value().toReal(); emit maxValueChanged(); } diff --git a/libnymea-app/models/logsmodelng.h b/libnymea-app/models/logsmodelng.h index 453b63e3..45dcccf5 100644 --- a/libnymea-app/models/logsmodelng.h +++ b/libnymea-app/models/logsmodelng.h @@ -32,8 +32,13 @@ #include #include +#include "engine.h" + class LogEntry; -class Engine; + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +using namespace QtCharts; +#endif class LogsModelNg : public QAbstractListModel, public QQmlParserStatus { @@ -50,7 +55,7 @@ class LogsModelNg : public QAbstractListModel, public QQmlParserStatus Q_PROPERTY(QVariant minValue READ minValue NOTIFY minValueChanged) Q_PROPERTY(QVariant maxValue READ maxValue NOTIFY maxValueChanged) - Q_PROPERTY(QtCharts::QXYSeries *graphSeries READ graphSeries WRITE setGraphSeries NOTIFY graphSeriesChanged) + Q_PROPERTY(QXYSeries *graphSeries READ graphSeries WRITE setGraphSeries NOTIFY graphSeriesChanged) Q_PROPERTY(QDateTime viewStartTime READ viewStartTime WRITE setViewStartTime NOTIFY viewStartTimeChanged) public: @@ -91,8 +96,8 @@ public: QDateTime endTime() const; void setEndTime(const QDateTime &endTime); - QtCharts::QXYSeries *graphSeries() const; - void setGraphSeries(QtCharts::QXYSeries *lineSeries); + QXYSeries *graphSeries() const; + void setGraphSeries(QXYSeries *lineSeries); QDateTime viewStartTime() const; void setViewStartTime(const QDateTime &viewStartTime); @@ -142,7 +147,7 @@ private: QVariant m_maxValue; bool m_ready = false; - QtCharts::QXYSeries *m_graphSeries = nullptr; + QXYSeries *m_graphSeries = nullptr; QList > m_fetchedPeriods; }; diff --git a/libnymea-app/models/nymeahostsfiltermodel.cpp b/libnymea-app/models/nymeahostsfiltermodel.cpp new file mode 100644 index 00000000..a26dd6e8 --- /dev/null +++ b/libnymea-app/models/nymeahostsfiltermodel.cpp @@ -0,0 +1,138 @@ +#include "nymeahostsfiltermodel.h" + +#include "jsonrpc/jsonrpcclient.h" + +NymeaHostsFilterModel::NymeaHostsFilterModel(QObject *parent): + QSortFilterProxyModel(parent) +{ + +} + +NymeaDiscovery *NymeaHostsFilterModel::discovery() const +{ + return m_nymeaDiscovery; +} + +void NymeaHostsFilterModel::setDiscovery(NymeaDiscovery *discovery) +{ + if (m_nymeaDiscovery != discovery) { + m_nymeaDiscovery = discovery; + setSourceModel(discovery->nymeaHosts()); + emit discoveryChanged(); + + connect(discovery->nymeaHosts(), &NymeaHosts::hostChanged, this, [this](){ +// qDebug() << "Host Changed!"; + invalidateFilter(); + emit countChanged(); + }); + + emit countChanged(); + } +} + +JsonRpcClient *NymeaHostsFilterModel::jsonRpcClient() const +{ + return m_jsonRpcClient; +} + +void NymeaHostsFilterModel::setJsonRpcClient(JsonRpcClient *jsonRpcClient) +{ + if (m_jsonRpcClient != jsonRpcClient) { + m_jsonRpcClient = jsonRpcClient; + emit jsonRpcClientChanged(); + + connect(m_jsonRpcClient, &JsonRpcClient::availableBearerTypesChanged, this, [this](){ +// qDebug() << "Bearer Types Changed!"; + invalidateFilter(); + emit countChanged(); + }); + + invalidateFilter(); + emit countChanged(); + } +} + +bool NymeaHostsFilterModel::showUnreachableBearers() const +{ + return m_showUneachableBearers; +} + +void NymeaHostsFilterModel::setShowUnreachableBearers(bool showUnreachableBearers) +{ + if (m_showUneachableBearers != showUnreachableBearers) { + m_showUneachableBearers = showUnreachableBearers; + emit showUnreachableBearersChanged(); + invalidateFilter(); + emit countChanged(); + } +} + +bool NymeaHostsFilterModel::showUnreachableHosts() const +{ + return m_showUneachableHosts; +} + +void NymeaHostsFilterModel::setShowUnreachableHosts(bool showUnreachableHosts) +{ + if (m_showUneachableHosts != showUnreachableHosts) { + m_showUneachableHosts = showUnreachableHosts; + emit showUnreachableHostsChanged(); + invalidateFilter(); + emit countChanged(); + } +} + +NymeaHost *NymeaHostsFilterModel::get(int index) const +{ + return m_nymeaDiscovery->nymeaHosts()->get(mapToSource(this->index(index, 0)).row()); +} + +bool NymeaHostsFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + Q_UNUSED(sourceParent) + NymeaHost *host = m_nymeaDiscovery->nymeaHosts()->get(sourceRow); + if (m_jsonRpcClient && !m_showUneachableBearers) { + bool hasReachableConnection = false; + for (int i = 0; i < host->connections()->rowCount(); i++) { +// qDebug() << "checking host for available bearer" << host->name() << host->connections()->get(i)->url() << "available bearer types:" << m_nymeaConnection->availableBearerTypes() << "hosts bearer types" << host->connections()->get(i)->bearerType(); + // Either enable a connection when the Bearer type is directly available + switch (host->connections()->get(i)->bearerType()) { + case Connection::BearerTypeLan: + hasReachableConnection |= m_jsonRpcClient->availableBearerTypes().testFlag(NymeaConnection::BearerTypeEthernet); + hasReachableConnection |= m_jsonRpcClient->availableBearerTypes().testFlag(NymeaConnection::BearerTypeWiFi); + break; + case Connection::BearerTypeWan: + case Connection::BearerTypeCloud: + hasReachableConnection |= m_jsonRpcClient->availableBearerTypes().testFlag(NymeaConnection::BearerTypeEthernet); + hasReachableConnection |= m_jsonRpcClient->availableBearerTypes().testFlag(NymeaConnection::BearerTypeWiFi); + hasReachableConnection |= m_jsonRpcClient->availableBearerTypes().testFlag(NymeaConnection::BearerTypeMobileData); + break; + case Connection::BearerTypeBluetooth: + hasReachableConnection |= m_jsonRpcClient->availableBearerTypes().testFlag(NymeaConnection::BearerTypeBluetooth); + break; + case Connection::BearerTypeUnknown: + case Connection::BearerTypeLoopback: + hasReachableConnection = true; + break; + case Connection::BearerTypeNone: + break; + } + } + if (!hasReachableConnection) { + return false; + } + } + if (!m_showUneachableHosts) { + bool isOnline = false; + for (int i = 0; i < host->connections()->rowCount(); i++) { + if (host->connections()->get(i)->online()) { + isOnline = true; + break; + } + } + if (!isOnline) { + return false; + } + } + return true; +} diff --git a/libnymea-app/models/nymeahostsfiltermodel.h b/libnymea-app/models/nymeahostsfiltermodel.h new file mode 100644 index 00000000..18f800b4 --- /dev/null +++ b/libnymea-app/models/nymeahostsfiltermodel.h @@ -0,0 +1,54 @@ +#ifndef NYMEAHOSTSFILTERMODEL_H +#define NYMEAHOSTSFILTERMODEL_H + +#include + +#include "connection/discovery/nymeadiscovery.h" +#include "jsonrpc/jsonrpcclient.h" + +class NymeaHostsFilterModel: public QSortFilterProxyModel +{ + Q_OBJECT + Q_PROPERTY(int count READ rowCount NOTIFY countChanged) + Q_PROPERTY(NymeaDiscovery* discovery READ discovery WRITE setDiscovery NOTIFY discoveryChanged) + Q_PROPERTY(JsonRpcClient* jsonRpcClient READ jsonRpcClient WRITE setJsonRpcClient NOTIFY jsonRpcClientChanged) + Q_PROPERTY(bool showUnreachableBearers READ showUnreachableBearers WRITE setShowUnreachableBearers NOTIFY showUnreachableBearersChanged) + Q_PROPERTY(bool showUnreachableHosts READ showUnreachableHosts WRITE setShowUnreachableHosts NOTIFY showUnreachableHostsChanged) + +public: + NymeaHostsFilterModel(QObject *parent = nullptr); + + NymeaDiscovery* discovery() const; + void setDiscovery(NymeaDiscovery *discovery); + + JsonRpcClient* jsonRpcClient() const; + void setJsonRpcClient(JsonRpcClient* jsonRpcClient); + + bool showUnreachableBearers() const; + void setShowUnreachableBearers(bool showUnreachableBearers); + + bool showUnreachableHosts() const; + void setShowUnreachableHosts(bool showUnreachableHosts); + + Q_INVOKABLE NymeaHost* get(int index) const; + +signals: + void countChanged(); + void discoveryChanged(); + void jsonRpcClientChanged(); + void showUnreachableBearersChanged(); + void showUnreachableHostsChanged(); + +protected: + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; + +private: + NymeaDiscovery *m_nymeaDiscovery = nullptr; + JsonRpcClient *m_jsonRpcClient = nullptr; + + bool m_showUneachableBearers = false; + bool m_showUneachableHosts = false; + +}; + +#endif // NYMEAHOSTSFILTERMODEL_H diff --git a/libnymea-app/models/rulesfiltermodel.h b/libnymea-app/models/rulesfiltermodel.h index 60087851..bf38a248 100644 --- a/libnymea-app/models/rulesfiltermodel.h +++ b/libnymea-app/models/rulesfiltermodel.h @@ -28,8 +28,7 @@ #include #include -class Rules; -class Rule; +#include "types/rules.h" class RulesFilterModel : public QSortFilterProxyModel { diff --git a/libnymea-app/models/sortfilterproxymodel.cpp b/libnymea-app/models/sortfilterproxymodel.cpp index 0e8eba50..7d5fb7f6 100644 --- a/libnymea-app/models/sortfilterproxymodel.cpp +++ b/libnymea-app/models/sortfilterproxymodel.cpp @@ -117,5 +117,5 @@ bool SortFilterProxyModel::lessThan(const QModelIndex &source_left, const QModel QVariant left = sourceModel()->data(source_left, sortRole); QVariant right = sourceModel()->data(source_right, sortRole); - return left <= right; + return left.toString() <= right.toString(); } diff --git a/libnymea-app/models/taglistmodel.h b/libnymea-app/models/taglistmodel.h index 5b93aff2..fba85a21 100644 --- a/libnymea-app/models/taglistmodel.h +++ b/libnymea-app/models/taglistmodel.h @@ -28,7 +28,7 @@ #include #include -class TagsProxyModel; +#include "tagsproxymodel.h" class Tag; class TagListModel : public QAbstractListModel diff --git a/libnymea-app/models/tagsproxymodel.cpp b/libnymea-app/models/tagsproxymodel.cpp index 366d7329..a8d10ae9 100644 --- a/libnymea-app/models/tagsproxymodel.cpp +++ b/libnymea-app/models/tagsproxymodel.cpp @@ -144,8 +144,8 @@ bool TagsProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_ qCDebug(dcTags) << "Filtering tag. ID:" << tag->tagId() << "Thing:" << tag->thingId() << "Value:" << tag->value(); qCDebug(dcTags) << "Filter: ID:" << m_filterTagId << "Thing:" << m_filterThingId << "value:" << m_filterValue; if (!m_filterTagId.isEmpty()) { - QRegExp exp(m_filterTagId); - if (!exp.exactMatch(tag->tagId())) { + QRegularExpression exp(m_filterTagId); + if (exp.match(tag->tagId()).hasMatch()) { return false; } } diff --git a/libnymea-app/models/tagsproxymodel.h b/libnymea-app/models/tagsproxymodel.h index a7476dfe..86c2d6b4 100644 --- a/libnymea-app/models/tagsproxymodel.h +++ b/libnymea-app/models/tagsproxymodel.h @@ -28,8 +28,7 @@ #include #include -class Tag; -class Tags; +#include "types/tags.h" class TagsProxyModel : public QSortFilterProxyModel { diff --git a/libnymea-app/models/wirelessaccesspointsproxy.h b/libnymea-app/models/wirelessaccesspointsproxy.h index 6c21ed74..b8eb4135 100644 --- a/libnymea-app/models/wirelessaccesspointsproxy.h +++ b/libnymea-app/models/wirelessaccesspointsproxy.h @@ -28,8 +28,7 @@ #include #include -class WirelessAccessPoint; -class WirelessAccessPoints; +#include "types/wirelessaccesspoints.h" class WirelessAccessPointsProxy : public QSortFilterProxyModel { diff --git a/libnymea-app/models/xyseriesadapter.cpp b/libnymea-app/models/xyseriesadapter.cpp index 864a1a15..65924925 100644 --- a/libnymea-app/models/xyseriesadapter.cpp +++ b/libnymea-app/models/xyseriesadapter.cpp @@ -49,12 +49,12 @@ void XYSeriesAdapter::setLogsModel(LogsModel *logsModel) } } -QtCharts::QXYSeries *XYSeriesAdapter::xySeries() const +QXYSeries *XYSeriesAdapter::xySeries() const { return m_series; } -void XYSeriesAdapter::setXySeries(QtCharts::QXYSeries *series) +void XYSeriesAdapter::setXySeries(QXYSeries *series) { if (m_series != series) { m_series = series; @@ -64,18 +64,18 @@ void XYSeriesAdapter::setXySeries(QtCharts::QXYSeries *series) } } -QtCharts::QXYSeries *XYSeriesAdapter::baseSeries() const +QXYSeries *XYSeriesAdapter::baseSeries() const { return m_baseSeries; } -void XYSeriesAdapter::setBaseSeries(QtCharts::QXYSeries *series) +void XYSeriesAdapter::setBaseSeries(QXYSeries *series) { if (m_baseSeries != series) { m_baseSeries = series; emit baseSeriesChanged(); - connect(m_baseSeries, &QtCharts::QXYSeries::pointAdded, this, [=](int index){ + connect(m_baseSeries, &QXYSeries::pointAdded, this, [=](int index){ if (m_series->count() > index) { qreal value = calculateSampleValue(index); m_series->replace(index, m_series->at(index).x(), value); @@ -91,7 +91,7 @@ void XYSeriesAdapter::setBaseSeries(QtCharts::QXYSeries *series) } } }); - connect(m_baseSeries, &QtCharts::QXYSeries::pointReplaced, this, [=](int index){ + connect(m_baseSeries, &QXYSeries::pointReplaced, this, [=](int index){ if (m_series->count() > index) { qreal value = calculateSampleValue(index); m_series->replace(index, m_series->at(index).x(), value); diff --git a/libnymea-app/models/xyseriesadapter.h b/libnymea-app/models/xyseriesadapter.h index bd14701e..0604c9d5 100644 --- a/libnymea-app/models/xyseriesadapter.h +++ b/libnymea-app/models/xyseriesadapter.h @@ -30,12 +30,16 @@ #include #include +#if QT_VERSION < QT_VERSION_CHECK(6, 0 ,0) +using namespace QtCharts; +#endif + class XYSeriesAdapter : public QObject { Q_OBJECT Q_PROPERTY(LogsModel* logsModel READ logsModel WRITE setLogsModel NOTIFY logsModelChanged) - Q_PROPERTY(QtCharts::QXYSeries* xySeries READ xySeries WRITE setXySeries NOTIFY xySeriesChanged) - Q_PROPERTY(QtCharts::QXYSeries* baseSeries READ baseSeries WRITE setBaseSeries NOTIFY baseSeriesChanged) + Q_PROPERTY(QXYSeries* xySeries READ xySeries WRITE setXySeries NOTIFY xySeriesChanged) + Q_PROPERTY(QXYSeries* baseSeries READ baseSeries WRITE setBaseSeries NOTIFY baseSeriesChanged) Q_PROPERTY(SampleRate sampleRate READ sampleRate WRITE setSampleRate NOTIFY sampleRateChanged) Q_PROPERTY(bool smooth READ smooth WRITE setSmooth NOTIFY smoothChanged) @@ -59,11 +63,11 @@ public: LogsModel* logsModel() const; void setLogsModel(LogsModel *logsModel); - QtCharts::QXYSeries* xySeries() const; - void setXySeries(QtCharts::QXYSeries *series); + QXYSeries* xySeries() const; + void setXySeries(QXYSeries *series); - QtCharts::QXYSeries* baseSeries() const; - void setBaseSeries(QtCharts::QXYSeries *series); + QXYSeries* baseSeries() const; + void setBaseSeries(QXYSeries *series); SampleRate sampleRate() const; void setSampleRate(SampleRate sampleRate); @@ -103,8 +107,8 @@ private: LogEntry *startingPoint = nullptr; // the starting point for the sample. Normally the last entry of the previous sample }; LogsModel* m_model = nullptr; - QtCharts::QXYSeries* m_series = nullptr; - QtCharts::QXYSeries* m_baseSeries = nullptr; + QXYSeries* m_series = nullptr; + QXYSeries* m_baseSeries = nullptr; SampleRate m_sampleRate = SampleRateSecond; bool m_smooth = true; bool m_inverted = false; diff --git a/libnymea-app/rulemanager.cpp b/libnymea-app/rulemanager.cpp index bda1e116..52ff0285 100644 --- a/libnymea-app/rulemanager.cpp +++ b/libnymea-app/rulemanager.cpp @@ -253,13 +253,13 @@ void RuleManager::parseEventDescriptors(const QVariantList &eventDescriptorList, { foreach (const QVariant &eventDescriptorVariant, eventDescriptorList) { EventDescriptor *eventDescriptor = new EventDescriptor(rule); - eventDescriptor->setThingId(eventDescriptorVariant.toMap().value("thingId").toString()); - eventDescriptor->setEventTypeId(eventDescriptorVariant.toMap().value("eventTypeId").toString()); + eventDescriptor->setThingId(eventDescriptorVariant.toMap().value("thingId").toUuid()); + eventDescriptor->setEventTypeId(eventDescriptorVariant.toMap().value("eventTypeId").toUuid()); 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(); - paramDescriptor->setParamTypeId(paramDescriptorVariant.toMap().value("paramTypeId").toString()); + paramDescriptor->setParamTypeId(paramDescriptorVariant.toMap().value("paramTypeId").toUuid()); paramDescriptor->setParamName(paramDescriptorVariant.toMap().value("paramName").toString()); paramDescriptor->setValue(paramDescriptorVariant.toMap().value("value")); QMetaEnum operatorEnum = QMetaEnum::fromType(); @@ -335,7 +335,7 @@ RuleAction *RuleManager::parseRuleAction(const QVariantMap &ruleAction) } foreach (const QVariant &ruleActionParamVariant, ruleAction.value("ruleActionParams").toList()) { RuleActionParam *param = new RuleActionParam(); - param->setParamTypeId(ruleActionParamVariant.toMap().value("paramTypeId").toString()); + param->setParamTypeId(ruleActionParamVariant.toMap().value("paramTypeId").toUuid()); param->setParamName(ruleActionParamVariant.toMap().value("paramName").toString()); param->setValue(ruleActionParamVariant.toMap().value("value")); param->setEventTypeId(ruleActionParamVariant.toMap().value("eventTypeId").toString()); diff --git a/libnymea-app/ruletemplates/ruleactiontemplate.h b/libnymea-app/ruletemplates/ruleactiontemplate.h index ecea5052..1c8d28b3 100644 --- a/libnymea-app/ruletemplates/ruleactiontemplate.h +++ b/libnymea-app/ruletemplates/ruleactiontemplate.h @@ -27,7 +27,8 @@ #include -class RuleActionParamTemplates; +#include "ruleactionparamtemplate.h" + class RuleActionTemplate : public QObject { diff --git a/libnymea-app/ruletemplates/ruletemplate.h b/libnymea-app/ruletemplates/ruletemplate.h index 0511e342..48cd28f5 100644 --- a/libnymea-app/ruletemplates/ruletemplate.h +++ b/libnymea-app/ruletemplates/ruletemplate.h @@ -27,10 +27,10 @@ #include -class EventDescriptorTemplates; -class RuleActionTemplates; -class StateEvaluatorTemplate; -class TimeDescriptorTemplate; +#include "eventdescriptortemplate.h" +#include "ruleactiontemplate.h" +#include "stateevaluatortemplate.h" +#include "timedescriptortemplate.h" class RuleTemplate : public QObject { diff --git a/libnymea-app/ruletemplates/ruletemplates.h b/libnymea-app/ruletemplates/ruletemplates.h index 6426d5c3..dc827263 100644 --- a/libnymea-app/ruletemplates/ruletemplates.h +++ b/libnymea-app/ruletemplates/ruletemplates.h @@ -26,12 +26,12 @@ #define RULETEMPLATES_H #include +#include "thingsproxy.h" class RuleTemplate; class StateEvaluatorTemplate; class TimeDescriptorTemplate; class RepeatingOption; -class ThingsProxy; class Thing; class RuleTemplates : public QAbstractListModel diff --git a/libnymea-app/ruletemplates/timedescriptortemplate.h b/libnymea-app/ruletemplates/timedescriptortemplate.h index 29aaa82e..84d4046c 100644 --- a/libnymea-app/ruletemplates/timedescriptortemplate.h +++ b/libnymea-app/ruletemplates/timedescriptortemplate.h @@ -27,8 +27,8 @@ #include -class CalendarItemTemplates; -class TimeEventItemTemplates; +#include "calendaritemtemplate.h" +#include "timeeventitemtemplate.h" class TimeDescriptorTemplate : public QObject { diff --git a/libnymea-app/scripting/codecompletion.cpp b/libnymea-app/scripting/codecompletion.cpp index 93065a88..08b1330d 100644 --- a/libnymea-app/scripting/codecompletion.cpp +++ b/libnymea-app/scripting/codecompletion.cpp @@ -191,21 +191,21 @@ void CodeCompletion::update() QList entries; - QRegExp thingIdExp(".*thingId: \"[a-zA-ZÀ-ž0-9- ]*"); - if (thingIdExp.exactMatch(blockText)) { + QRegularExpression thingIdExp(".*thingId: \"[a-zA-ZÀ-ž0-9- ]*"); + if (thingIdExp.match(blockText).hasMatch()) { for (int i = 0; i < m_engine->thingManager()->things()->rowCount(); i++) { Thing *thing = m_engine->thingManager()->things()->get(i); entries.append(CompletionModel::Entry(thing->id().toString() + "\" // " + thing->name(), thing->name(), "thing", thing->thingClass()->interfaces().join(","))); } - blockText.remove(QRegExp(".*thingId: \"")); + blockText.remove(QRegularExpression(".*thingId: \"")); m_model->update(entries); m_proxy->setFilter(blockText, false); emit hint(); return; } - QRegExp stateTypeIdExp(".*stateTypeId: \"[a-zA-Z0-9-]*"); - if (stateTypeIdExp.exactMatch(blockText)) { + QRegularExpression stateTypeIdExp(".*stateTypeId: \"[a-zA-Z0-9-]*"); + if (stateTypeIdExp.match(blockText).hasMatch()) { BlockInfo info = getBlockInfo(m_cursor.position()); QString thingId; if (!info.properties.contains("thingId")) { @@ -214,7 +214,7 @@ void CodeCompletion::update() thingId = info.properties.value("thingId"); qDebug() << "selected thingId" << thingId; - Thing *thing = m_engine->thingManager()->things()->getThing(thingId); + Thing *thing = m_engine->thingManager()->things()->getThing(QUuid(thingId)); if (!thing) { return; } @@ -223,16 +223,16 @@ void CodeCompletion::update() StateType *stateType = thing->thingClass()->stateTypes()->get(i); entries.append(CompletionModel::Entry(stateType->id().toString() + "\" // " + stateType->name(), stateType->name(), "stateType")); } - blockText.remove(QRegExp(".*stateTypeId: \"")); + blockText.remove(QRegularExpression(".*stateTypeId: \"")); m_model->update(entries); m_proxy->setFilter(blockText); emit hint(); return; } - QRegExp stateNameExp(".*stateName: \"[a-zA-Z0-9-]*"); + QRegularExpression stateNameExp(".*stateName: \"[a-zA-Z0-9-]*"); // qDebug() << "block text" << blockText << stateNameExp.exactMatch(blockText); - if (stateNameExp.exactMatch(blockText)) { + if (stateNameExp.match(blockText).hasMatch()) { BlockInfo info = getBlockInfo(m_cursor.position()); qDebug() << "stateName block info" << info.name << info.properties; QString thingId; @@ -258,20 +258,28 @@ void CodeCompletion::update() } else { return; } - for (int i = 0; i < stateTypes->rowCount(); i++) { - StateType *stateType = stateTypes->get(i); + thingId = info.properties.value("thingId"); + + qDebug() << "selected thingId" << thingId; + Thing *thing = m_engine->thingManager()->things()->getThing(QUuid(thingId)); + if (!thing) { + return; + } + qDebug() << "Thing is" << thing->name(); + + for (int i = 0; i < thing->thingClass()->stateTypes()->rowCount(); i++) { + StateType *stateType = thing->thingClass()->stateTypes()->get(i); entries.append(CompletionModel::Entry(stateType->name() + "\"", stateType->name(), "stateType")); } - - blockText.remove(QRegExp(".*stateName: \"")); + blockText.remove(QRegularExpression(".*stateName: \"")); m_model->update(entries); m_proxy->setFilter(blockText); emit hint(); return; } - QRegExp actionTypeIdExp(".*actionTypeId: \"[a-zA-Z0-9-]*"); - if (actionTypeIdExp.exactMatch(blockText)) { + QRegularExpression actionTypeIdExp(".*actionTypeId: \"[a-zA-Z0-9-]*"); + if (actionTypeIdExp.match(blockText).hasMatch()) { BlockInfo info = getBlockInfo(m_cursor.position()); QString thingId; if (!info.properties.contains("thingId")) { @@ -280,7 +288,7 @@ void CodeCompletion::update() thingId = info.properties.value("thingId"); qDebug() << "selected thingId" << thingId; - Thing *thing = m_engine->thingManager()->things()->getThing(thingId); + Thing *thing = m_engine->thingManager()->things()->getThing(QUuid(thingId)); if (!thing) { return; } @@ -289,15 +297,15 @@ void CodeCompletion::update() ActionType *actionType = thing->thingClass()->actionTypes()->get(i); entries.append(CompletionModel::Entry(actionType->id().toString() + "\" // " + actionType->name(), actionType->name(), "actionType")); } - blockText.remove(QRegExp(".*actionTypeId: \"")); + blockText.remove(QRegularExpression(".*actionTypeId: \"")); m_model->update(entries); m_proxy->setFilter(blockText); emit hint(); return; } - QRegExp actionNameExp(".*actionName: \"[a-zA-Z0-9-]*"); - if (actionNameExp.exactMatch(blockText)) { + QRegularExpression actionNameExp(".*actionName: \"[a-zA-Z0-9-]*"); + if (actionNameExp.match(blockText).hasMatch()) { BlockInfo info = getBlockInfo(m_cursor.position()); Interfaces ifaces; @@ -306,7 +314,7 @@ void CodeCompletion::update() if (info.properties.contains("thingId")) { QString thingId = info.properties.value("thingId"); qDebug() << "selected thingId" << thingId; - Thing *thing = m_engine->thingManager()->things()->getThing(thingId); + Thing *thing = m_engine->thingManager()->things()->getThing(QUuid(thingId)); if (!thing) { return; } @@ -327,15 +335,15 @@ void CodeCompletion::update() entries.append(CompletionModel::Entry(actionType->name() + "\"", actionType->name(), "actionType")); } - blockText.remove(QRegExp(".*actionName: \"")); + blockText.remove(QRegularExpression(".*actionName: \"")); m_model->update(entries); m_proxy->setFilter(blockText); emit hint(); return; } - QRegExp eventTypeIdExp(".*eventTypeId: \"[a-zA-Z0-9-]*"); - if (eventTypeIdExp.exactMatch(blockText)) { + QRegularExpression eventTypeIdExp(".*eventTypeId: \"[a-zA-Z0-9-]*"); + if (eventTypeIdExp.match(blockText).hasMatch()) { BlockInfo info = getBlockInfo(m_cursor.position()); QString thingId; if (!info.properties.contains("thingId")) { @@ -344,7 +352,7 @@ void CodeCompletion::update() thingId = info.properties.value("thingId"); qDebug() << "selected thingId" << thingId; - Thing *thing= m_engine->thingManager()->things()->getThing(thingId); + Thing *thing= m_engine->thingManager()->things()->getThing(QUuid(thingId)); if (!thing) { return; } @@ -353,21 +361,21 @@ void CodeCompletion::update() EventType *eventType = thing->thingClass()->eventTypes()->get(i); entries.append(CompletionModel::Entry(eventType->id().toString() + "\" // " + eventType->name(), eventType->name(), "eventType")); } - blockText.remove(QRegExp(".*eventTypeId: \"")); + blockText.remove(QRegularExpression(".*eventTypeId: \"")); m_model->update(entries); m_proxy->setFilter(blockText); emit hint(); return; } - QRegExp eventNameExp(".*eventName: \"[a-zA-Z0-9-]*"); - if (eventNameExp.exactMatch(blockText)) { + QRegularExpression eventNameExp(".*eventName: \"[a-zA-Z0-9-]*"); + if (eventNameExp.match(blockText).hasMatch()) { BlockInfo info = getBlockInfo(m_cursor.position()); Interfaces ifaces; EventTypes *eventTypes = nullptr; if (info.properties.contains("thingId")) { QString thingId = info.properties.value("thingId"); - Thing *thing = m_engine->thingManager()->things()->getThing(thingId); + Thing *thing = m_engine->thingManager()->things()->getThing(QUuid(thingId)); if (!thing) { return; } @@ -388,15 +396,15 @@ void CodeCompletion::update() EventType *eventType = eventTypes->get(i); entries.append(CompletionModel::Entry(eventType->name() + "\"", eventType->name(), "eventType")); } - blockText.remove(QRegExp(".*eventName: \"")); + blockText.remove(QRegularExpression(".*eventName: \"")); m_model->update(entries); m_proxy->setFilter(blockText); emit hint(); return; } - QRegExp interfaceNameExp(".*(interfaceName|filterInterface): \"[a-zA-Z]*"); - if (interfaceNameExp.exactMatch(blockText)) { + QRegularExpression interfaceNameExp(".*interfaceName: \"[a-zA-Z]*"); + if (interfaceNameExp.match(blockText).hasMatch()) { BlockInfo info = getBlockInfo(m_cursor.position()); Interfaces ifaces; @@ -405,22 +413,22 @@ void CodeCompletion::update() entries.append(CompletionModel::Entry(iface->name() + "\"", iface->name(), "interface", iface->name())); } m_model->update(entries); - blockText.remove(QRegExp(".*(interfaceName|filterInterface): \"")); + blockText.remove(QRegularExpression(".*interfaceName: \"")); m_proxy->setFilter(blockText); emit hint(); return; } - QRegExp importExp("imp(o|or)?"); - if (importExp.exactMatch(blockText)) { + QRegularExpression importExp("imp(o|or)?"); + if (importExp.match(blockText).hasMatch()) { entries.append(CompletionModel::Entry("import ", "import", "keyword", "")); m_model->update(entries); m_proxy->setFilter(blockText); return; } - QRegExp importExp2("import [a-zA-Z]*"); - if (importExp2.exactMatch(blockText)) { + QRegularExpression importExp2("import [a-zA-Z]*"); + if (importExp2.match(blockText).hasMatch()) { entries.append(CompletionModel::Entry("QtQuick 2.0")); entries.append(CompletionModel::Entry("nymea 1.0")); m_model->update(entries); @@ -429,8 +437,8 @@ void CodeCompletion::update() return; } - QRegExp rValueExp(" *[\\.a-zA-Z0-0]+[^id]:[ a-zA-Z0-0]*"); - if (rValueExp.exactMatch(blockText)) { + QRegularExpression rValueExp(" *[\\.a-zA-Z0-0]+[^id]:[ a-zA-Z0-0]*"); + if (rValueExp.match(blockText).hasMatch()) { QTextCursor tmp = m_cursor; tmp.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor); QString word = tmp.selectedText(); @@ -458,10 +466,10 @@ void CodeCompletion::update() return; } - QRegExp dotExp(".*[a-zA-Z0-9]+\\.[a-zA-Z0-9]*"); - if (dotExp.exactMatch(blockText)) { + QRegularExpression dotExp(".*[a-zA-Z0-9]+\\.[a-zA-Z0-9]*"); + if (dotExp.match(blockText).hasMatch()) { QString id = blockText; - id.remove(QRegExp(".* ")).remove(QRegExp("\\.[a-zA-Z0-9]*")); + id.remove(QRegularExpression(".* ")).remove(QRegularExpression("\\.[a-zA-Z0-9]*")); QString type = getIdTypes().value(id); int blockPosition = getBlockPosition(id); BlockInfo blockInfo = getBlockInfo(blockPosition); @@ -497,7 +505,7 @@ void CodeCompletion::update() if (d) { ActionType *at = nullptr; if (blockInfo.properties.contains("actionTypeId")) { - at = d->thingClass()->actionTypes()->getActionType(blockInfo.properties.value("actionTypeId")); + at = d->thingClass()->actionTypes()->getActionType(QUuid(blockInfo.properties.value("actionTypeId"))); } else if (blockInfo.properties.contains("actionName")) { at = d->thingClass()->actionTypes()->findByName(blockInfo.properties.value("actionName")); } @@ -542,7 +550,7 @@ void CodeCompletion::update() entries.append(CompletionModel::Entry(method + "(", method, "method", "", ")")); } m_model->update(entries); - m_proxy->setFilter(blockText.remove(QRegExp(".*\\."))); + m_proxy->setFilter(blockText.remove(QRegularExpression(".*\\."))); return; } @@ -564,8 +572,8 @@ void CodeCompletion::update() if (isImperative) { // qDebug() << "Is imperative!"; // Starting a new expression? - QRegExp newExpressionExp("(.*; [a-zA-Z0-9]*| *[a-zA-Z0-9]*)"); - if (newExpressionExp.exactMatch(blockText)) { + QRegularExpression newExpressionExp("(.*; [a-zA-Z0-9]*| *[a-zA-Z0-9]*)"); + if (newExpressionExp.match(blockText).hasMatch()) { // Add generic qml syntax foreach (const QString &s, m_genericJsSyntax.keys()) { entries.append(CompletionModel::Entry(m_genericJsSyntax.value(s), s, "keyword", "")); @@ -579,12 +587,12 @@ void CodeCompletion::update() } m_model->update(entries); - m_proxy->setFilter(blockText.remove(QRegExp(".* "))); + m_proxy->setFilter(blockText.remove(QRegularExpression(".* "))); return; } - QRegExp lValueStartExp(" *[a-zA-Z0-9]*"); - if (lValueStartExp.exactMatch(blockText)) { + QRegularExpression lValueStartExp(" *[a-zA-Z0-9]*"); + if (lValueStartExp.match(blockText).hasMatch()) { BlockInfo blockInfo = getBlockInfo(m_cursor.position()); // If we're inside a class, add properties @@ -617,7 +625,7 @@ void CodeCompletion::update() } m_model->update(entries); - blockText.remove(QRegExp(".* ")); + blockText.remove(QRegularExpression(".* ")); m_proxy->setFilter(blockText); // qDebug() << "Model has" << m_model->rowCount() << "Filtered:" << m_proxy->rowCount() << "filter:" << blockText; return; @@ -658,9 +666,9 @@ CodeCompletion::BlockInfo CodeCompletion::getBlockInfo(int position) const // qDebug() << "Block start:" << info.start << "end:" << info.end; info.name = blockStart.block().text(); - info.name.remove(QRegExp(" *\\{ *")); + info.name.remove(QRegularExpression(" *\\{ *")); while (info.name.contains(" ")) { - info.name.remove(QRegExp(".* ")); + info.name.remove(QRegularExpression(".* ")); } int childBlocks = 0; @@ -760,7 +768,7 @@ int CodeCompletion::openingBlocksBefore(int position) const QTextCursor tmp = m_cursor; tmp.setPosition(position); do { - tmp = m_document->textDocument()->find(QRegExp("[{}]"), tmp, QTextDocument::FindBackward); + tmp = m_document->textDocument()->find(QRegularExpression("[{}]"), tmp, QTextDocument::FindBackward); if (tmp.selectedText() == "{") opening++; if (tmp.selectedText() == "}") @@ -777,7 +785,7 @@ int CodeCompletion::closingBlocksAfter(int position) const QTextCursor tmp = m_cursor; tmp.setPosition(position); do { - tmp = m_document->textDocument()->find(QRegExp("[{}]"), tmp); + tmp = m_document->textDocument()->find(QRegularExpression("[{}]"), tmp); if (tmp.selectedText() == "{") opening++; if (tmp.selectedText() == "}") @@ -802,8 +810,8 @@ void CodeCompletion::complete(int index) QTextCursor tmp = m_cursor; tmp.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); QString blockText = tmp.selectedText(); - QRegExp thingIdExp(".*thingId: \"[a-zA-ZÀ-ž0-9- ]*"); - if (thingIdExp.exactMatch(blockText)) { + QRegularExpression thingIdExp(".*thingId: \"[a-zA-ZÀ-ž0-9- ]*"); + if (thingIdExp.match(blockText).hasMatch()) { QTextCursor tmp = m_document->textDocument()->find("\"", m_cursor.position(), QTextDocument::FindBackward); m_cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, m_cursor.position() - tmp.position()); m_cursor.removeSelectedText(); @@ -827,7 +835,7 @@ void CodeCompletion::newLine() } QString trimmedLine = line; - trimmedLine.remove(QRegExp("^[ ]+")); + trimmedLine.remove(QRegularExpression("^[ ]+")); int indent = line.length() - trimmedLine.length(); m_cursor.insertText(QString("\n").leftJustified(indent + 1, ' ')); @@ -926,7 +934,7 @@ void CodeCompletion::toggleComment(int from, int to) bool allLinesHaveComments = true; do { - QTextCursor nextComment = m_document->textDocument()->find(QRegExp("^[ ]*//"), tmp.position()); + QTextCursor nextComment = m_document->textDocument()->find(QRegularExpression("^[ ]*//"), tmp.position()); nextComment.movePosition(QTextCursor::StartOfLine); bool lineHasComment = tmp.position() == nextComment.position(); allLinesHaveComments &= lineHasComment; @@ -939,7 +947,7 @@ void CodeCompletion::toggleComment(int from, int to) tmp.movePosition(QTextCursor::StartOfLine); do { if (allLinesHaveComments) { - QTextCursor nextComment = m_document->textDocument()->find(QRegExp("//"), tmp.position()); + QTextCursor nextComment = m_document->textDocument()->find(QRegularExpression("//"), tmp.position()); nextComment.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 2); nextComment.removeSelectedText(); nextComment.insertText(" "); @@ -970,7 +978,7 @@ void CodeCompletion::moveCursor(CodeCompletion::MoveOperation moveOperation, int return; case MoveOperationPreviousWord: { // We're not using the cursors next/previos word because we want camelCase word fragments - QTextCursor tmp = m_document->textDocument()->find(QRegExp("[A-Z\\.:\"'\\(\\)\\[\\]^ ]"), m_cursor.position() - 1, QTextDocument::FindBackward); + QTextCursor tmp = m_document->textDocument()->find(QRegularExpression("[A-Z\\.:\"'\\(\\)\\[\\]^ ]"), m_cursor.position() - 1, QTextDocument::FindBackward); qWarning() << "found at" << tmp.position() << "starting at" << m_cursor.position(); m_cursor.setPosition(tmp.position()); emit cursorPositionChanged(); @@ -978,7 +986,7 @@ void CodeCompletion::moveCursor(CodeCompletion::MoveOperation moveOperation, int } case MoveOperationNextWord: { // We're not using the cursors next/previos word because we want camelCase word fragments - QTextCursor tmp = m_document->textDocument()->find(QRegExp("[A-Z\\.:\"'\\(\\)\\[\\]$ ]"), m_cursor.position() + 1); + QTextCursor tmp = m_document->textDocument()->find(QRegularExpression("[A-Z\\.:\"'\\(\\)\\[\\]$ ]"), m_cursor.position() + 1); m_cursor.setPosition(tmp.position() - 1); emit cursorPositionChanged(); return; diff --git a/libnymea-app/scripting/codecompletion.h b/libnymea-app/scripting/codecompletion.h index 47da880b..3ca3da62 100644 --- a/libnymea-app/scripting/codecompletion.h +++ b/libnymea-app/scripting/codecompletion.h @@ -30,10 +30,9 @@ #include #include +#include "engine.h" #include "completionmodel.h" -class Engine; - class CodeCompletion: public QObject { Q_OBJECT diff --git a/libnymea-app/scripting/scriptautosaver.cpp b/libnymea-app/scripting/scriptautosaver.cpp index 095ab9ec..ef051e67 100644 --- a/libnymea-app/scripting/scriptautosaver.cpp +++ b/libnymea-app/scripting/scriptautosaver.cpp @@ -27,6 +27,7 @@ #include #include #include +#include ScriptAutoSaver::ScriptAutoSaver(QObject *parent) : QObject(parent) { @@ -80,7 +81,7 @@ void ScriptAutoSaver::setScriptId(const QUuid &scriptId) qWarning() << "Cannot create cache directory. Autosaving will not work..."; return; } - QString fileName = path + m_scriptId.toString().remove(QRegExp("[{}]")) + ".qml.autosave"; + QString fileName = path + m_scriptId.toString().remove(QRegularExpression("[{}]")) + ".qml.autosave"; m_cacheFile.setFileName(fileName); if (!m_cacheFile.open(QFile::ReadWrite)) { qWarning() << "Cannot open cache file. Autosaving will not work..."; diff --git a/libnymea-app/scriptmanager.h b/libnymea-app/scriptmanager.h index c951313d..73d4be6b 100644 --- a/libnymea-app/scriptmanager.h +++ b/libnymea-app/scriptmanager.h @@ -28,8 +28,7 @@ #include #include "jsonrpc/jsonrpcclient.h" - -class Scripts; +#include "types/scripts.h" class ScriptManager : public QObject { diff --git a/libnymea-app/system/systemcontroller.h b/libnymea-app/system/systemcontroller.h index 2c17247e..84a441a8 100644 --- a/libnymea-app/system/systemcontroller.h +++ b/libnymea-app/system/systemcontroller.h @@ -28,9 +28,8 @@ #include #include "jsonrpc/jsonrpcclient.h" - -class Repositories; -class Packages; +#include "types/packages.h" +#include "types/repositories.h" class SystemController : public QObject { diff --git a/libnymea-app/tagsmanager.cpp b/libnymea-app/tagsmanager.cpp index e5c5b9ca..00131d7d 100644 --- a/libnymea-app/tagsmanager.cpp +++ b/libnymea-app/tagsmanager.cpp @@ -177,15 +177,15 @@ void TagsManager::removeTagResponse(int commandId, const QVariantMap ¶ms) Tag* TagsManager::unpackTag(const QVariantMap &tagMap) { - QString thingId = tagMap.value("thingId").toString(); - QString ruleId = tagMap.value("ruleId").toString(); + QUuid thingId = tagMap.value("thingId").toUuid(); + QUuid ruleId = tagMap.value("ruleId").toUuid(); QString tagId = tagMap.value("tagId").toString(); QString value = tagMap.value("value").toString(); Tag *tag = nullptr; - if (!thingId.isEmpty()) { + if (!thingId.isNull()) { tag = new Tag(tagId, value); tag->setThingId(thingId); - } else if (!ruleId.isEmpty()) { + } else if (!ruleId.isNull()) { tag = new Tag(tagId, value); tag->setRuleId(ruleId); } else { diff --git a/libnymea-app/tagwatcher.h b/libnymea-app/tagwatcher.h index e88cd007..7b8f3371 100644 --- a/libnymea-app/tagwatcher.h +++ b/libnymea-app/tagwatcher.h @@ -28,6 +28,7 @@ #include #include +#include "types/tag.h" #include "types/tags.h" class TagWatcher : public QObject diff --git a/libnymea-app/thingdiscovery.cpp b/libnymea-app/thingdiscovery.cpp index df059e70..f71e5f6b 100644 --- a/libnymea-app/thingdiscovery.cpp +++ b/libnymea-app/thingdiscovery.cpp @@ -182,7 +182,7 @@ void ThingDiscovery::discoverThingsResponse(int commandId, const QVariantMap &pa beginInsertRows(QModelIndex(), m_foundThings.count(), m_foundThings.count()); ThingDescriptor *descriptor = new ThingDescriptor(descriptorVariant.toMap().value("id").toUuid(), descriptorVariant.toMap().value("thingClassId").toUuid(), // Note: This will only be provided as of nymea 0.28! - descriptorVariant.toMap().value("thingId").toString(), + descriptorVariant.toMap().value("thingId").toUuid(), descriptorVariant.toMap().value("title").toString(), descriptorVariant.toMap().value("description").toString(), this); // Work around a bug in nymea:core which didn't properly update deviceParams in the device->things transition @@ -194,7 +194,7 @@ void ThingDiscovery::discoverThingsResponse(int commandId, const QVariantMap &pa } foreach (const QVariant ¶mVariant, paramList) { qDebug() << "Adding param:" << paramVariant.toMap().value("paramTypeId").toString() << paramVariant.toMap().value("value"); - Param* p = new Param(paramVariant.toMap().value("paramTypeId").toString(), paramVariant.toMap().value("value")); + Param* p = new Param(paramVariant.toMap().value("paramTypeId").toUuid(), paramVariant.toMap().value("value")); descriptor->params()->addParam(p); } qCInfo(dcThingManager()) << "Found thing. Descriptor:" << descriptor->name() << descriptor->id(); diff --git a/libnymea-app/thingmanager.cpp b/libnymea-app/thingmanager.cpp index bdc225a5..3fff48c8 100644 --- a/libnymea-app/thingmanager.cpp +++ b/libnymea-app/thingmanager.cpp @@ -175,7 +175,7 @@ void ThingManager::notificationReceived(const QVariantMap &data) } } else if (notification == "Integrations.ThingSettingChanged") { QUuid thingId = data.value("params").toMap().value("thingId").toUuid(); - QString paramTypeId = data.value("params").toMap().value("paramTypeId").toString(); + QUuid paramTypeId = data.value("params").toMap().value("paramTypeId").toUuid(); QVariant value = data.value("params").toMap().value("value"); // qDebug() << "Thing settings changed notification for thing" << thingId << data.value("params").toMap().value("settings").toList(); Thing *thing = m_things->getThing(thingId); @@ -202,7 +202,7 @@ void ThingManager::notificationReceived(const QVariantMap &data) return; } qCDebug(dcThingManager) << "Event received" << thingId.toString() << eventTypeId.toString() << qUtf8Printable(QJsonDocument::fromVariant(event).toJson()); - thing->eventTriggered(eventTypeId.toString(), event.value("params").toList()); + thing->eventTriggered(eventTypeId, event.value("params").toList()); } else if (notification == "Integrations.IOConnectionAdded") { QVariantMap connectionMap = data.value("params").toMap().value("ioConnection").toMap(); QUuid id = connectionMap.value("id").toUuid(); @@ -280,7 +280,7 @@ void ThingManager::getThingsResponse(int /*commandId*/, const QVariantMap ¶m // set initial state values QVariantList stateVariantList = thingVariant.toMap().value("states").toList(); foreach (const QVariant &stateMap, stateVariantList) { - QString stateTypeId = stateMap.toMap().value("stateTypeId").toString(); + QUuid stateTypeId = stateMap.toMap().value("stateTypeId").toUuid(); StateType *st = thing->thingClass()->stateTypes()->getStateType(stateTypeId); if (!st) { qWarning() << "Can't find a statetype for this state"; @@ -725,7 +725,7 @@ void ThingManager::setEventLoggingResponse(int commandId, const QVariantMap &par Vendor *ThingManager::unpackVendor(const QVariantMap &vendorMap) { - Vendor *v = new Vendor(vendorMap.value("id").toString(), vendorMap.value("name").toString()); + Vendor *v = new Vendor(vendorMap.value("id").toUuid(), vendorMap.value("name").toString()); v->setDisplayName(vendorMap.value("displayName").toString()); return v; } @@ -817,14 +817,14 @@ ThingClass *ThingManager::unpackThingClass(const QVariantMap &thingClassMap) void ThingManager::unpackParam(const QVariantMap ¶mMap, Param *param) { - param->setParamTypeId(paramMap.value("paramTypeId").toString()); + param->setParamTypeId(paramMap.value("paramTypeId").toUuid()); param->setValue(paramMap.value("value")); } ParamType *ThingManager::unpackParamType(const QVariantMap ¶mTypeMap, QObject *parent) { ParamType *paramType = new ParamType(parent); - paramType->setId(paramTypeMap.value("id").toString()); + paramType->setId(paramTypeMap.value("id").toUuid()); paramType->setName(paramTypeMap.value("name").toString()); paramType->setDisplayName(paramTypeMap.value("displayName").toString()); paramType->setType(paramTypeMap.value("type").toString()); @@ -842,7 +842,7 @@ ParamType *ThingManager::unpackParamType(const QVariantMap ¶mTypeMap, QObjec StateType *ThingManager::unpackStateType(const QVariantMap &stateTypeMap, QObject *parent) { StateType *stateType = new StateType(parent); - stateType->setId(stateTypeMap.value("id").toString()); + stateType->setId(stateTypeMap.value("id").toUuid()); stateType->setName(stateTypeMap.value("name").toString()); stateType->setDisplayName(stateTypeMap.value("displayName").toString()); stateType->setIndex(stateTypeMap.value("index").toInt()); @@ -870,7 +870,7 @@ StateType *ThingManager::unpackStateType(const QVariantMap &stateTypeMap, QObjec EventType *ThingManager::unpackEventType(const QVariantMap &eventTypeMap, QObject *parent) { EventType *eventType = new EventType(parent); - eventType->setId(eventTypeMap.value("id").toString()); + eventType->setId(eventTypeMap.value("id").toUuid()); eventType->setName(eventTypeMap.value("name").toString()); eventType->setDisplayName(eventTypeMap.value("displayName").toString()); eventType->setIndex(eventTypeMap.value("index").toInt()); @@ -885,7 +885,7 @@ EventType *ThingManager::unpackEventType(const QVariantMap &eventTypeMap, QObjec ActionType *ThingManager::unpackActionType(const QVariantMap &actionTypeMap, QObject *parent) { ActionType *actionType = new ActionType(parent); - actionType->setId(actionTypeMap.value("id").toString()); + actionType->setId(actionTypeMap.value("id").toUuid()); actionType->setName(actionTypeMap.value("name").toString()); actionType->setDisplayName(actionTypeMap.value("displayName").toString()); actionType->setIndex(actionTypeMap.value("index").toInt()); @@ -937,7 +937,7 @@ Thing* ThingManager::unpackThing(ThingManager *thingManager, const QVariantMap & params = new Params(thing); } foreach (QVariant param, thingMap.value("params").toList()) { - Param *p = params->getParam(param.toMap().value("paramTypeId").toString()); + Param *p = params->getParam(param.toMap().value("paramTypeId").toUuid()); if (!p) { p = new Param(); params->addParam(p); @@ -951,7 +951,7 @@ Thing* ThingManager::unpackThing(ThingManager *thingManager, const QVariantMap & settings = new Params(thing); } foreach (QVariant setting, thingMap.value("settings").toList()) { - Param *p = settings->getParam(setting.toMap().value("paramTypeId").toString()); + Param *p = settings->getParam(setting.toMap().value("paramTypeId").toUuid()); if (!p) { p = new Param(); settings->addParam(p); diff --git a/libnymea-app/thingmanager.h b/libnymea-app/thingmanager.h index 328f96b9..41df07a9 100644 --- a/libnymea-app/thingmanager.h +++ b/libnymea-app/thingmanager.h @@ -30,16 +30,16 @@ #include "types/vendors.h" #include "things.h" #include "thingclasses.h" -#include "interfacesmodel.h" #include "types/plugins.h" #include "jsonrpc/jsonrpcclient.h" +#include "types/ioconnections.h" class BrowserItem; class BrowserItems; class ThingGroup; class Interface; -class IOConnections; class EventHandler; +class ThingsProxy; class ThingManager : public QObject { diff --git a/libnymea-app/thingsproxy.cpp b/libnymea-app/thingsproxy.cpp index 87230107..4599e467 100644 --- a/libnymea-app/thingsproxy.cpp +++ b/libnymea-app/thingsproxy.cpp @@ -253,7 +253,7 @@ void ThingsProxy::setHiddenThingClassIds(const QStringList &hiddenThingClassIds) { QList uuids; foreach (const QString &str, hiddenThingClassIds) { - uuids << str; + uuids.append(QUuid(str)); } if (m_hiddenThingClassIds != uuids) { m_hiddenThingClassIds = uuids; @@ -297,7 +297,7 @@ void ThingsProxy::setHiddenThingIds(const QStringList &hiddenThingIds) { QList uuids; foreach (const QString &str, hiddenThingIds) { - uuids << str; + uuids.append(QUuid(str)); } if (m_hiddenThingIds != uuids) { m_hiddenThingIds = uuids; @@ -610,7 +610,7 @@ bool ThingsProxy::lessThan(const QModelIndex &left, const QModelIndex &right) co State *rightState = rightThing->stateByName(m_sortStateName); QVariant leftStateValue = leftState ? leftState->value() : 0; QVariant rightStateValue = rightState ? rightState->value() : 0; - return leftStateValue < rightStateValue; + return leftStateValue.toString() < rightStateValue.toString(); } QString leftName = sourceModel()->data(left, sortRole()).toString(); @@ -631,7 +631,7 @@ bool ThingsProxy::filterAcceptsRow(int source_row, const QModelIndex &source_par { Thing *thing = getInternal(source_row); if (!m_filterTagId.isEmpty()) { - Tag *tag = m_engine->tagsManager()->tags()->findThingTag(thing->id().toString(), m_filterTagId); + Tag *tag = m_engine->tagsManager()->tags()->findThingTag(thing->id(), m_filterTagId); if (!tag) { return false; } @@ -640,7 +640,7 @@ bool ThingsProxy::filterAcceptsRow(int source_row, const QModelIndex &source_par } } if (!m_hideTagId.isEmpty()) { - Tag *tag = m_engine->tagsManager()->tags()->findThingTag(thing->id().toString(), m_hideTagId); + Tag *tag = m_engine->tagsManager()->tags()->findThingTag(thing->id(), m_hideTagId); if (tag && m_hideTagValue.isEmpty()) { return false; } diff --git a/libnymea-app/thingsproxy.h b/libnymea-app/thingsproxy.h index 2f4653a2..cc2e434f 100644 --- a/libnymea-app/thingsproxy.h +++ b/libnymea-app/thingsproxy.h @@ -29,10 +29,9 @@ #include #include +#include "engine.h" #include "things.h" -class Engine; - class ThingsProxy : public QSortFilterProxyModel { Q_OBJECT diff --git a/libnymea-app/types/calendaritem.h b/libnymea-app/types/calendaritem.h index 603cefa5..368c49c8 100644 --- a/libnymea-app/types/calendaritem.h +++ b/libnymea-app/types/calendaritem.h @@ -28,7 +28,7 @@ #include #include -class RepeatingOption; +#include "repeatingoption.h" class CalendarItem : public QObject { diff --git a/libnymea-app/types/interface.h b/libnymea-app/types/interface.h index 4f6d8650..9b456e2a 100644 --- a/libnymea-app/types/interface.h +++ b/libnymea-app/types/interface.h @@ -27,9 +27,10 @@ #include -class EventTypes; -class StateTypes; -class ActionTypes; +#include "eventtypes.h" +#include "statetypes.h" +#include "actiontypes.h" + class ThingClass; class Interface : public QObject diff --git a/libnymea-app/types/ioconnectionwatcher.h b/libnymea-app/types/ioconnectionwatcher.h index 2fb69c93..dd8b2612 100644 --- a/libnymea-app/types/ioconnectionwatcher.h +++ b/libnymea-app/types/ioconnectionwatcher.h @@ -28,8 +28,8 @@ #include #include -class IOConnection; -class IOConnections; +#include "ioconnection.h" +#include "ioconnections.h" class IOInputConnectionWatcher : public QObject { diff --git a/libnymea-app/types/networkdevice.h b/libnymea-app/types/networkdevice.h index b7ed2705..ae2f0636 100644 --- a/libnymea-app/types/networkdevice.h +++ b/libnymea-app/types/networkdevice.h @@ -27,8 +27,8 @@ #include -class WirelessAccessPoint; -class WirelessAccessPoints; +#include "wirelessaccesspoint.h" +#include "wirelessaccesspoints.h" class NetworkDevice : public QObject { diff --git a/libnymea-app/types/param.h b/libnymea-app/types/param.h index ddd3e5c6..626878d7 100644 --- a/libnymea-app/types/param.h +++ b/libnymea-app/types/param.h @@ -36,7 +36,7 @@ class Param : public QObject Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged) public: - Param(const QUuid ¶mTypeId = QString(), const QVariant &value = QVariant(), QObject *parent = nullptr); + Param(const QUuid ¶mTypeId = QUuid(), const QVariant &value = QVariant(), QObject *parent = nullptr); Param(QObject *parent); QUuid paramTypeId() const; diff --git a/libnymea-app/types/paramdescriptors.cpp b/libnymea-app/types/paramdescriptors.cpp index c15f9c3b..b6791a3b 100644 --- a/libnymea-app/types/paramdescriptors.cpp +++ b/libnymea-app/types/paramdescriptors.cpp @@ -82,7 +82,7 @@ void ParamDescriptors::addParamDescriptor(ParamDescriptor *paramDescriptor) emit countChanged(); } -void ParamDescriptors::setParamDescriptor(const QString ¶mTypeId, const QVariant &value, ValueOperator operatorType) +void ParamDescriptors::setParamDescriptor(const QUuid ¶mTypeId, const QVariant &value, ValueOperator operatorType) { foreach (ParamDescriptor* paramDescriptor, m_list) { if (paramDescriptor->paramTypeId() == paramTypeId) { @@ -125,7 +125,7 @@ void ParamDescriptors::clear() emit countChanged(); } -ParamDescriptor *ParamDescriptors::getParamDescriptor(const QString ¶mTypeId) const +ParamDescriptor *ParamDescriptors::getParamDescriptor(const QUuid ¶mTypeId) const { qDebug() << "getParamDescriptor" << paramTypeId; for (int i = 0; i < m_list.count(); i++) { diff --git a/libnymea-app/types/paramdescriptors.h b/libnymea-app/types/paramdescriptors.h index a03cd0ef..01d128c6 100644 --- a/libnymea-app/types/paramdescriptors.h +++ b/libnymea-app/types/paramdescriptors.h @@ -62,11 +62,11 @@ public: ParamDescriptor* createNewParamDescriptor() const; void addParamDescriptor(ParamDescriptor* paramDescriptor); - Q_INVOKABLE void setParamDescriptor(const QString ¶mTypeId, const QVariant &value, ValueOperator operatorType); + Q_INVOKABLE void setParamDescriptor(const QUuid ¶mTypeId, const QVariant &value, ValueOperator operatorType); Q_INVOKABLE void setParamDescriptorByName(const QString ¶mName, const QVariant &value, ValueOperator operatorType); Q_INVOKABLE void clear(); - Q_INVOKABLE ParamDescriptor *getParamDescriptor(const QString ¶mTypeId) const; + Q_INVOKABLE ParamDescriptor *getParamDescriptor(const QUuid ¶mTypeId) const; Q_INVOKABLE ParamDescriptor *getParamDescriptorByName(const QString ¶mName) const; bool operator==(ParamDescriptors *other) const; diff --git a/libnymea-app/types/rule.cpp b/libnymea-app/types/rule.cpp index 58891ca8..56fcf75d 100644 --- a/libnymea-app/types/rule.cpp +++ b/libnymea-app/types/rule.cpp @@ -207,17 +207,17 @@ bool Rule::operator==(Rule *other) const QDebug operator <<(QDebug &dbg, Rule *rule) { - dbg << rule->name() << " (Enabled:" << rule->enabled() << "Active:" << rule->active() << ")" << endl; + dbg << rule->name() << " (Enabled:" << rule->enabled() << "Active:" << rule->active() << ")" << Qt::endl; if (rule->eventDescriptors()->rowCount() > 0) { - dbg << "Event descriptors:" << endl; + dbg << "Event descriptors:" << Qt::endl; } for (int i = 0; i < rule->eventDescriptors()->rowCount(); i++) { EventDescriptor *ed = rule->eventDescriptors()->get(i); dbg << " " << i << ":"; if (!ed->thingId().isNull() && !ed->eventTypeId().isNull()) { - dbg << "Thing ID:" << ed->thingId() << "Event Type ID:" << ed->eventTypeId() << endl; + dbg << "Thing ID:" << ed->thingId() << "Event Type ID:" << ed->eventTypeId() << Qt::endl; } else { - dbg << "Interface Name:" << ed->interfaceName() << "Event Name:" << ed->interfaceEvent() << endl; + dbg << "Interface Name:" << ed->interfaceName() << "Event Name:" << ed->interfaceEvent() << Qt::endl; } for (int j = 0; j < ed->paramDescriptors()->rowCount(); j++) { ParamDescriptor *epd = ed->paramDescriptors()->get(j); @@ -242,52 +242,52 @@ QDebug operator <<(QDebug &dbg, Rule *rule) operatorString = ">="; break; } - dbg << " Param" << j << ": ID:" << epd->paramTypeId() << operatorString << " Value:" << epd->value() << endl; + dbg << " Param" << j << ": ID:" << epd->paramTypeId() << operatorString << " Value:" << epd->value() << Qt::endl; } } if (rule->stateEvaluator()) { - dbg << "State Evaluator:" << endl; + dbg << "State Evaluator:" << Qt::endl; printStateEvaluator(dbg, rule->stateEvaluator()); } if (rule->actions()->rowCount() > 0) { - dbg << "Actions:" << endl; + dbg << "Actions:" << Qt::endl; } for (int i = 0; i < rule->actions()->rowCount(); i++) { RuleAction *ra = rule->actions()->get(i); dbg << " " << i << ":"; if (!ra->thingId().isNull() && !ra->actionTypeId().isNull()) { - dbg << "Thing ID:" << ra->thingId() << "Action Type ID:" << ra->actionTypeId() << endl; + dbg << "Thing ID:" << ra->thingId() << "Action Type ID:" << ra->actionTypeId() << Qt::endl; } else { - dbg << "Interface Name:" << ra->interfaceName() << "Action Name:" << ra->interfaceAction() << endl; + dbg << "Interface Name:" << ra->interfaceName() << "Action Name:" << ra->interfaceAction() << Qt::endl; } for (int j = 0; j < ra->ruleActionParams()->rowCount(); j++) { RuleActionParam *rap = ra->ruleActionParams()->get(j); if (rap->eventTypeId().isNull()) { - dbg << " Param" << j << ": ID:" << rap->paramTypeId() << " Value:" << rap->value() << endl; + dbg << " Param" << j << ": ID:" << rap->paramTypeId() << " Value:" << rap->value() << Qt::endl; } else { - dbg << " Param" << j << ": ID:" << rap->paramTypeId() << " Source Event Type ID:" << rap->eventTypeId() << "Source Event Param ID:" << rap->eventParamTypeId() << endl; + dbg << " Param" << j << ": ID:" << rap->paramTypeId() << " Source Event Type ID:" << rap->eventTypeId() << "Source Event Param ID:" << rap->eventParamTypeId() << Qt::endl; } } } if (rule->exitActions()->rowCount() > 0) { - dbg << "Exit Actions:" << endl; + dbg << "Exit Actions:" << Qt::endl; } for (int i = 0; i < rule->exitActions()->rowCount(); i++) { RuleAction *ra = rule->exitActions()->get(i); dbg << " " << i << ":"; if (!ra->thingId().isNull() && !ra->actionTypeId().isNull()) { - dbg << "Thing ID:" << ra->thingId() << "Action Type ID:" << ra->actionTypeId() << endl;; + dbg << "Thing ID:" << ra->thingId() << "Action Type ID:" << ra->actionTypeId() << Qt::endl;; } else { - dbg << "Interface Name:" << ra->interfaceName() << "Action Name:" << ra->interfaceAction() << endl;; + dbg << "Interface Name:" << ra->interfaceName() << "Action Name:" << ra->interfaceAction() << Qt::endl;; } for (int j = 0; j < ra->ruleActionParams()->rowCount(); j++) { RuleActionParam *rap = ra->ruleActionParams()->get(j); if (rap->eventTypeId().isNull()) { - dbg << " Param" << j << ": ID:" << rap->paramTypeId() << " Value:" << rap->value() << endl; + dbg << " Param" << j << ": ID:" << rap->paramTypeId() << " Value:" << rap->value() << Qt::endl; } else { - dbg << " Param" << j << ": ID:" << rap->paramTypeId() << " Source Event Type ID:" << rap->eventTypeId() << "Source Event Param ID:" << rap->eventParamTypeId() << endl; + dbg << " Param" << j << ": ID:" << rap->paramTypeId() << " Source Event Type ID:" << rap->eventTypeId() << "Source Event Param ID:" << rap->eventParamTypeId() << Qt::endl; } } } @@ -324,11 +324,11 @@ QDebug printStateEvaluator(QDebug &dbg, StateEvaluator *stateEvaluator, int inde dbg << ">="; break; } - dbg << stateEvaluator->stateDescriptor()->value() << '/' << stateEvaluator->stateDescriptor()->valueThingId() << stateEvaluator->stateDescriptor()->valueStateTypeId() << endl; + dbg << stateEvaluator->stateDescriptor()->value() << '/' << stateEvaluator->stateDescriptor()->valueThingId() << stateEvaluator->stateDescriptor()->valueStateTypeId() << Qt::endl; } if (stateEvaluator->childEvaluators()->rowCount() > 0) { for (int i = 0; i < indentLevel; i++) { dbg << " "; } - dbg << (stateEvaluator->stateOperator() == StateEvaluator::StateOperatorAnd ? "AND" : "OR") << endl; + dbg << (stateEvaluator->stateOperator() == StateEvaluator::StateOperatorAnd ? "AND" : "OR") << Qt::endl; } for (int i = 0; i < stateEvaluator->childEvaluators()->rowCount(); i++) { printStateEvaluator(dbg, stateEvaluator->childEvaluators()->get(i), indentLevel+1); diff --git a/libnymea-app/types/rule.h b/libnymea-app/types/rule.h index 5e9bcbef..ef185172 100644 --- a/libnymea-app/types/rule.h +++ b/libnymea-app/types/rule.h @@ -28,10 +28,10 @@ #include #include -class EventDescriptors; -class RuleActions; -class StateEvaluator; -class TimeDescriptor; +#include "eventdescriptors.h" +#include "ruleactions.h" +#include "stateevaluator.h" +#include "timedescriptor.h" class Rule : public QObject { diff --git a/libnymea-app/types/ruleaction.h b/libnymea-app/types/ruleaction.h index a6e910a3..458b031d 100644 --- a/libnymea-app/types/ruleaction.h +++ b/libnymea-app/types/ruleaction.h @@ -28,7 +28,7 @@ #include #include -class RuleActionParams; +#include "ruleactionparams.h" class RuleAction : public QObject { diff --git a/libnymea-app/types/ruleactionparams.cpp b/libnymea-app/types/ruleactionparams.cpp index 58ad9d3d..9d68e48e 100644 --- a/libnymea-app/types/ruleactionparams.cpp +++ b/libnymea-app/types/ruleactionparams.cpp @@ -103,7 +103,7 @@ void RuleActionParams::setRuleActionParamByName(const QString ¶mName, const addRuleActionParam(rap); } -void RuleActionParams::setRuleActionParamEvent(const QString ¶mTypeId, const QString &eventTypeId, const QString &eventParamTypeId) +void RuleActionParams::setRuleActionParamEvent(const QUuid ¶mTypeId, const QString &eventTypeId, const QString &eventParamTypeId) { foreach (RuleActionParam *rap, m_list) { if (rap->paramTypeId() == paramTypeId) { @@ -135,7 +135,7 @@ void RuleActionParams::setRuleActionParamEventByName(const QString ¶mName, c addRuleActionParam(rap); } -void RuleActionParams::setRuleActionParamState(const QString ¶mTypeId, const QString &stateThingId, const QString &stateTypeId) +void RuleActionParams::setRuleActionParamState(const QUuid ¶mTypeId, const QString &stateThingId, const QString &stateTypeId) { foreach (RuleActionParam *rap, m_list) { if (rap->paramTypeId() == paramTypeId) { @@ -185,7 +185,7 @@ RuleActionParam *RuleActionParams::getParam(const QUuid ¶mTypeId) return nullptr; } -bool RuleActionParams::hasRuleActionParam(const QString ¶mTypeId) const +bool RuleActionParams::hasRuleActionParam(const QUuid ¶mTypeId) const { for (int i = 0; i < m_list.count(); i++) { if (m_list.at(i)->paramTypeId() == paramTypeId) { diff --git a/libnymea-app/types/ruleactionparams.h b/libnymea-app/types/ruleactionparams.h index 802803be..1dd6e5f6 100644 --- a/libnymea-app/types/ruleactionparams.h +++ b/libnymea-app/types/ruleactionparams.h @@ -52,15 +52,15 @@ public: Q_INVOKABLE void setRuleActionParam(const QUuid ¶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 void setRuleActionParamEvent(const QUuid ¶mTypeId, const QString &eventTypeId, const QString &eventParamTypeId); Q_INVOKABLE void setRuleActionParamEventByName(const QString ¶mName, const QString &eventTypeId, const QString &eventParamTypeId); - Q_INVOKABLE void setRuleActionParamState(const QString ¶mTypeId, const QString &stateThingId, const QString &stateTypeId); + Q_INVOKABLE void setRuleActionParamState(const QUuid ¶mTypeId, const QString &stateThingId, const QString &stateTypeId); Q_INVOKABLE void setRuleActionParamStateByName(const QString ¶mName, const QString &stateThingId, const QString &stateTypeId); Q_INVOKABLE RuleActionParam* get(int index) const; Q_INVOKABLE RuleActionParam* getParam(const QUuid ¶mTypeId); - Q_INVOKABLE bool hasRuleActionParam(const QString ¶mTypeId) const; + Q_INVOKABLE bool hasRuleActionParam(const QUuid ¶mTypeId) const; Q_INVOKABLE void clear(); diff --git a/libnymea-app/types/stateevaluator.h b/libnymea-app/types/stateevaluator.h index 6ed61000..78d66f55 100644 --- a/libnymea-app/types/stateevaluator.h +++ b/libnymea-app/types/stateevaluator.h @@ -27,8 +27,8 @@ #include -class StateEvaluators; -class StateDescriptor; +#include "stateevaluators.h" +#include "statedescriptor.h" class StateEvaluator : public QObject { diff --git a/libnymea-app/types/tags.cpp b/libnymea-app/types/tags.cpp index 314c9ea0..bc7dc169 100644 --- a/libnymea-app/types/tags.cpp +++ b/libnymea-app/types/tags.cpp @@ -125,7 +125,7 @@ Tag *Tags::findThingTag(const QUuid &thingId, const QString &tagId) const return nullptr; } -Tag *Tags::findRuleTag(const QString &ruleId, const QString &tagId) const +Tag *Tags::findRuleTag(const QUuid &ruleId, const QString &tagId) const { foreach (Tag *tag, m_list) { if (tag->ruleId() == ruleId && tag->tagId() == tagId) { diff --git a/libnymea-app/types/tags.h b/libnymea-app/types/tags.h index c210e840..7f7cf002 100644 --- a/libnymea-app/types/tags.h +++ b/libnymea-app/types/tags.h @@ -55,7 +55,7 @@ public: Q_INVOKABLE Tag* get(int index) const; Q_INVOKABLE Tag* findThingTag(const QUuid &thingId, const QString &tagId) const; - Q_INVOKABLE Tag* findRuleTag(const QString &ruleId, const QString &tagId) const; + Q_INVOKABLE Tag* findRuleTag(const QUuid &ruleId, const QString &tagId) const; void clear(); diff --git a/libnymea-app/types/thing.cpp b/libnymea-app/types/thing.cpp index e2152cf1..6b8d351e 100644 --- a/libnymea-app/types/thing.cpp +++ b/libnymea-app/types/thing.cpp @@ -279,29 +279,29 @@ int Thing::executeAction(const QString &actionName, const QVariantList ¶ms) QDebug operator<<(QDebug &dbg, Thing *thing) { - dbg.nospace() << "Thing: " << thing->name() << " (" << thing->id().toString() << ") Class:" << thing->thingClass()->name() << " (" << thing->thingClassId().toString() << ")" << endl; + dbg.nospace() << "Thing: " << thing->name() << " (" << thing->id().toString() << ") Class:" << thing->thingClass()->name() << " (" << thing->thingClassId().toString() << ")" << Qt::endl; for (int i = 0; i < thing->thingClass()->paramTypes()->rowCount(); i++) { ParamType *pt = thing->thingClass()->paramTypes()->get(i); - Param *p = thing->params()->getParam(pt->id().toString()); + Param *p = thing->params()->getParam(pt->id()); if (p) { - dbg << " Param " << i << ": " << pt->id().toString() << ": " << pt->name() << " = " << p->value() << endl; + dbg << " Param " << i << ": " << pt->id().toString() << ": " << pt->name() << " = " << p->value() << Qt::endl; } else { - dbg << " Param " << i << ": " << pt->id().toString() << ": " << pt->name() << " = " << "*** Unknown value ***" << endl; + dbg << " Param " << i << ": " << pt->id().toString() << ": " << pt->name() << " = " << "*** Unknown value ***" << Qt::endl; } } for (int i = 0; i < thing->thingClass()->settingsTypes()->rowCount(); i++) { ParamType *pt = thing->thingClass()->settingsTypes()->get(i); - Param *p = thing->settings()->getParam(pt->id().toString()); + Param *p = thing->settings()->getParam(pt->id()); if (p) { - dbg << " Setting " << i << ": " << pt->id().toString() << ": " << pt->name() << " = " << p->value() << endl; + dbg << " Setting " << i << ": " << pt->id().toString() << ": " << pt->name() << " = " << p->value() << Qt::endl; } else { - dbg << " Setting " << i << ": " << pt->id().toString() << ": " << pt->name() << " = " << "*** Unknown value ***" << endl; + dbg << " Setting " << i << ": " << pt->id().toString() << ": " << pt->name() << " = " << "*** Unknown value ***" << Qt::endl; } } for (int i = 0; i < thing->thingClass()->stateTypes()->rowCount(); i++) { StateType *st = thing->thingClass()->stateTypes()->get(i); State *s = thing->states()->getState(st->id()); - dbg << " State " << i << ": " << st->id() << ": " << st->name() << " = " << s->value() << endl; + dbg << " State " << i << ": " << st->id() << ": " << st->name() << " = " << s->value() << Qt::endl; } return dbg; } diff --git a/libnymea-app/types/thing.h b/libnymea-app/types/thing.h index 2a731138..c3979537 100644 --- a/libnymea-app/types/thing.h +++ b/libnymea-app/types/thing.h @@ -31,8 +31,7 @@ #include "params.h" #include "states.h" #include "statesproxy.h" - -class ThingClass; +#include "thingclass.h" class ThingManager; class Thing : public QObject diff --git a/libnymea-app/types/thingclass.cpp b/libnymea-app/types/thingclass.cpp index 0ba7f5b5..a9358286 100644 --- a/libnymea-app/types/thingclass.cpp +++ b/libnymea-app/types/thingclass.cpp @@ -321,7 +321,7 @@ void ThingClass::setBrowserItemActionTypes(ActionTypes *browserActionTypes) emit browserItemActionTypesChanged(); } -bool ThingClass::hasActionType(const QString &actionTypeId) +bool ThingClass::hasActionType(const QUuid &actionTypeId) { foreach (ActionType *actionType, m_actionTypes->actionTypes()) { if (actionType->id() == actionTypeId) { diff --git a/libnymea-app/types/thingclass.h b/libnymea-app/types/thingclass.h index 943d4dff..ae4c905d 100644 --- a/libnymea-app/types/thingclass.h +++ b/libnymea-app/types/thingclass.h @@ -133,7 +133,7 @@ public: ActionTypes *browserItemActionTypes() const; void setBrowserItemActionTypes(ActionTypes *browserActionTypes); - Q_INVOKABLE bool hasActionType(const QString &actionTypeId); + Q_INVOKABLE bool hasActionType(const QUuid &actionTypeId); signals: void paramTypesChanged(); diff --git a/libnymea-app/types/timedescriptor.h b/libnymea-app/types/timedescriptor.h index 68c8e08f..06f7c95b 100644 --- a/libnymea-app/types/timedescriptor.h +++ b/libnymea-app/types/timedescriptor.h @@ -29,8 +29,8 @@ #include -class TimeEventItems; -class CalendarItems; +#include "timeeventitems.h" +#include "calendaritems.h" class TimeDescriptor : public QObject { diff --git a/libnymea-app/types/timeeventitem.h b/libnymea-app/types/timeeventitem.h index fbf375a9..dab564d8 100644 --- a/libnymea-app/types/timeeventitem.h +++ b/libnymea-app/types/timeeventitem.h @@ -29,7 +29,7 @@ #include #include -class RepeatingOption; +#include "repeatingoption.h" class TimeEventItem : public QObject { diff --git a/libnymea-app/usermanager.cpp b/libnymea-app/usermanager.cpp index ebc1daf0..1f56581b 100644 --- a/libnymea-app/usermanager.cpp +++ b/libnymea-app/usermanager.cpp @@ -219,7 +219,7 @@ void UserManager::getTokensResponse(int /*commandId*/, const QVariantMap &data) foreach (const QVariant &tokenVariant, data.value("tokenInfoList").toList()) { // qDebug() << "Token received" << tokenVariant.toMap(); QVariantMap token = tokenVariant.toMap(); - QUuid id = token.value("id").toString(); + QUuid id = token.value("id").toUuid(); QString username = token.value("username").toString(); QString deviceName = token.value("deviceName").toString(); QDateTime creationTime = QDateTime::fromSecsSinceEpoch(token.value("creationTime").toInt()); diff --git a/libnymea-app/wifisetup/bluetoothdeviceinfos.cpp b/libnymea-app/wifisetup/bluetoothdeviceinfos.cpp index ef6f3c94..021df6a0 100644 --- a/libnymea-app/wifisetup/bluetoothdeviceinfos.cpp +++ b/libnymea-app/wifisetup/bluetoothdeviceinfos.cpp @@ -176,8 +176,8 @@ QString BluetoothDeviceInfosProxy::filterForServiceUUID() const void BluetoothDeviceInfosProxy::setFilterForServiceUUID(const QString &filterForServiceUUID) { - if (m_filterForServiceUUID != filterForServiceUUID) { - m_filterForServiceUUID = filterForServiceUUID; + if (m_filterForServiceUUID != QBluetoothUuid(filterForServiceUUID)) { + m_filterForServiceUUID = QBluetoothUuid(filterForServiceUUID); emit filterForServiceUUIDChanged(); invalidateFilter(); emit countChanged(); diff --git a/libnymea-app/wifisetup/bluetoothdeviceinfos.h b/libnymea-app/wifisetup/bluetoothdeviceinfos.h index e5f2f60b..cba21deb 100644 --- a/libnymea-app/wifisetup/bluetoothdeviceinfos.h +++ b/libnymea-app/wifisetup/bluetoothdeviceinfos.h @@ -29,6 +29,7 @@ #include #include #include +#include #include "bluetoothdeviceinfo.h" @@ -115,7 +116,7 @@ private: BluetoothDeviceInfos *m_model = nullptr; QStringList m_nameWhitelist; bool m_filterForLowEnergy = false; - QUuid m_filterForServiceUUID; + QBluetoothUuid m_filterForServiceUUID; QString m_filterForName; }; diff --git a/libnymea-app/wifisetup/btwifisetup.cpp b/libnymea-app/wifisetup/btwifisetup.cpp index 64f4fb61..ad153b65 100644 --- a/libnymea-app/wifisetup/btwifisetup.cpp +++ b/libnymea-app/wifisetup/btwifisetup.cpp @@ -99,8 +99,12 @@ void BtWiFiSetup::connectToDevice(const BluetoothDeviceInfo *device) m_accessPoints->clearModel(); }, Qt::QueuedConnection); +#if QT_VERSION < QT_VERSION_CHECK(6, 2, 0) typedef void (QLowEnergyController::*errorsSignal)(QLowEnergyController::Error); connect(m_btController, static_cast(&QLowEnergyController::error), this, [this](QLowEnergyController::Error error){ +#else + connect(m_btController, &QLowEnergyController::errorOccurred, this, [this](QLowEnergyController::Error error){ +#endif qCWarning(dcBtWiFiSetup()) << "Bluetooth error:" << error; emit this->bluetoothConnectionError(); }, Qt::QueuedConnection); @@ -255,7 +259,7 @@ WirelessAccessPoint *BtWiFiSetup::currentConnection() const void BtWiFiSetup::setupServices() { qCDebug(dcBtWiFiSetup()) << "Setting up Bluetooth services"; - m_deviceInformationService = m_btController->createServiceObject(QBluetoothUuid::DeviceInformation, m_btController); + m_deviceInformationService = m_btController->createServiceObject(QBluetoothUuid::ServiceClassUuid::DeviceInformation, m_btController); m_networkService = m_btController->createServiceObject(networkServiceUuid, m_btController); m_wifiService = m_btController->createServiceObject(wifiServiceUuid, m_btController); m_systemService = m_btController->createServiceObject(systemServiceUuid, m_btController); @@ -277,15 +281,15 @@ void BtWiFiSetup::setupServices() if (state != QLowEnergyService::ServiceDiscovered) return; qCDebug(dcBtWiFiSetup()) << "Device info service discovered"; - m_manufacturer = QString::fromUtf8(m_deviceInformationService->characteristic(QBluetoothUuid::ManufacturerNameString).value()); + m_manufacturer = QString::fromUtf8(m_deviceInformationService->characteristic(QBluetoothUuid::CharacteristicType::ManufacturerNameString).value()); emit manufacturerChanged(); - m_modelNumber = QString::fromUtf8(m_deviceInformationService->characteristic(QBluetoothUuid::ModelNumberString).value()); + m_modelNumber = QString::fromUtf8(m_deviceInformationService->characteristic(QBluetoothUuid::CharacteristicType::ModelNumberString).value()); emit modelNumberChanged(); - m_softwareRevision = QString::fromUtf8(m_deviceInformationService->characteristic(QBluetoothUuid::SoftwareRevisionString).value()); + m_softwareRevision = QString::fromUtf8(m_deviceInformationService->characteristic(QBluetoothUuid::CharacteristicType::SoftwareRevisionString).value()); emit softwareRevisionChanged(); - m_firmwareRevision = QString::fromUtf8(m_deviceInformationService->characteristic(QBluetoothUuid::FirmwareRevisionString).value()); + m_firmwareRevision = QString::fromUtf8(m_deviceInformationService->characteristic(QBluetoothUuid::CharacteristicType::FirmwareRevisionString).value()); emit firmwareRevisionChanged(); - m_hardwareRevision = QString::fromUtf8(m_deviceInformationService->characteristic(QBluetoothUuid::HardwareRevisionString).value()); + m_hardwareRevision = QString::fromUtf8(m_deviceInformationService->characteristic(QBluetoothUuid::CharacteristicType::HardwareRevisionString).value()); emit hardwareRevisionChanged(); }); m_deviceInformationService->discoverDetails(); @@ -305,9 +309,9 @@ void BtWiFiSetup::setupServices() return; } // Enable notifications - m_networkService->writeDescriptor(networkCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); - m_networkService->writeDescriptor(networkingEnabledCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); - m_networkService->writeDescriptor(wirelessEnabledCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); + m_networkService->writeDescriptor(networkCharacteristic.descriptor(QBluetoothUuid::DescriptorType::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); + m_networkService->writeDescriptor(networkingEnabledCharacteristic.descriptor(QBluetoothUuid::DescriptorType::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); + m_networkService->writeDescriptor(wirelessEnabledCharacteristic.descriptor(QBluetoothUuid::DescriptorType::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); m_networkStatus = static_cast(networkCharacteristic.value().toHex().toUInt(nullptr, 16)); emit networkStatusChanged(); @@ -330,8 +334,8 @@ void BtWiFiSetup::setupServices() m_wifiService->readCharacteristic(m_wifiService->characteristic(wifiServiceVersionCharacteristicUuid)); // Enable notifations - m_wifiService->writeDescriptor(m_wifiService->characteristic(wifiResponseCharacteristicUuid).descriptor(QBluetoothUuid::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); - m_wifiService->writeDescriptor(m_wifiService->characteristic(wifiStatusCharacteristicUuid).descriptor(QBluetoothUuid::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); + m_wifiService->writeDescriptor(m_wifiService->characteristic(wifiResponseCharacteristicUuid).descriptor(QBluetoothUuid::DescriptorType::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); + m_wifiService->writeDescriptor(m_wifiService->characteristic(wifiStatusCharacteristicUuid).descriptor(QBluetoothUuid::DescriptorType::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); qCDebug(dcBtWiFiSetup()) << "Fetching networks after init"; loadNetworks(); @@ -347,7 +351,7 @@ void BtWiFiSetup::setupServices() if (state != QLowEnergyService::ServiceDiscovered) return; qCDebug(dcBtWiFiSetup()) << "System service discovered"; - m_systemService->writeDescriptor(m_systemService->characteristic(systemResponseCharacteristicUuid).descriptor(QBluetoothUuid::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); + m_systemService->writeDescriptor(m_systemService->characteristic(systemResponseCharacteristicUuid).descriptor(QBluetoothUuid::DescriptorType::ClientCharacteristicConfiguration), QByteArray::fromHex("0100")); }); m_systemService->discoverDetails(); } diff --git a/libnymea-app/wifisetup/btwifisetup.h b/libnymea-app/wifisetup/btwifisetup.h index 22d5f8bc..854496c6 100644 --- a/libnymea-app/wifisetup/btwifisetup.h +++ b/libnymea-app/wifisetup/btwifisetup.h @@ -28,10 +28,9 @@ #include #include #include - -class BluetoothDeviceInfo; -class WirelessAccessPoints; -class WirelessAccessPoint; +#include "types/wirelessaccesspoint.h" +#include "types/wirelessaccesspoints.h" +#include "bluetoothdeviceinfo.h" class BtWiFiSetup : public QObject { diff --git a/libnymea-app/zigbee/zigbeeadaptersproxy.h b/libnymea-app/zigbee/zigbeeadaptersproxy.h index b065a3ba..afd7afaf 100644 --- a/libnymea-app/zigbee/zigbeeadaptersproxy.h +++ b/libnymea-app/zigbee/zigbeeadaptersproxy.h @@ -28,8 +28,9 @@ #include #include +#include "zigbeemanager.h" + class ZigbeeAdapter; -class ZigbeeManager; class ZigbeeAdaptersProxy : public QSortFilterProxyModel { diff --git a/libnymea-app/zigbee/zigbeemanager.h b/libnymea-app/zigbee/zigbeemanager.h index 8613e4d0..268150c9 100644 --- a/libnymea-app/zigbee/zigbeemanager.h +++ b/libnymea-app/zigbee/zigbeemanager.h @@ -26,13 +26,11 @@ #define ZIGBEEMANAGER_H #include -#include "zigbeeadapter.h" +#include "zigbeeadapters.h" +#include "zigbeenetworks.h" +#include "engine.h" -class Engine; class JsonRpcClient; -class ZigbeeAdapters; -class ZigbeeNetwork; -class ZigbeeNetworks; class ZigbeeNode; class ZigbeeNodes; class ZigbeeNodeBinding; diff --git a/libnymea-app/zigbee/zigbeenodes.h b/libnymea-app/zigbee/zigbeenodes.h index 42657aa4..bfd69e8c 100644 --- a/libnymea-app/zigbee/zigbeenodes.h +++ b/libnymea-app/zigbee/zigbeenodes.h @@ -78,4 +78,6 @@ protected: }; +Q_DECLARE_METATYPE(ZigbeeNodes*) + #endif // ZIGBEENODES_H diff --git a/libnymea-app/zigbee/zigbeenodesproxy.h b/libnymea-app/zigbee/zigbeenodesproxy.h index cf4929e2..e63eacb3 100644 --- a/libnymea-app/zigbee/zigbeenodesproxy.h +++ b/libnymea-app/zigbee/zigbeenodesproxy.h @@ -29,7 +29,7 @@ #include #include "zigbeenode.h" -class ZigbeeNodes; +#include "zigbeenodes.h" class ZigbeeNodesProxy : public QSortFilterProxyModel { diff --git a/nymea-app/dashboard/dashboarditem.h b/nymea-app/dashboard/dashboarditem.h index 4f14a6d9..79025521 100644 --- a/nymea-app/dashboard/dashboarditem.h +++ b/nymea-app/dashboard/dashboarditem.h @@ -28,8 +28,8 @@ #include #include #include +#include "dashboardmodel.h" -class DashboardModel; class DashboardItem : public QObject { diff --git a/nymea-app/main.cpp b/nymea-app/main.cpp index 0e8a6d7a..6fc679c7 100644 --- a/nymea-app/main.cpp +++ b/nymea-app/main.cpp @@ -32,6 +32,12 @@ #include #include #include "utils/qhashqml.h" +#include +#include +#include +#include +#include +#include #include "libnymea-app-core.h" #include "libnymea-app-airconditioning.h" @@ -139,8 +145,10 @@ int main(int argc, char *argv[]) QString defaultStyle; if (parser.isSet(defaultStyleOption)) { defaultStyle = parser.value(defaultStyleOption); +#ifndef DISABLE_DARK_MODE } else if (PlatformHelper::instance()->darkModeEnabled()) { defaultStyle = "dark"; +#endif } else { defaultStyle = "light"; } diff --git a/nymea-app/nfchelper.cpp b/nymea-app/nfchelper.cpp index c36c48bb..6e07bc6b 100644 --- a/nymea-app/nfchelper.cpp +++ b/nymea-app/nfchelper.cpp @@ -48,5 +48,9 @@ QObject *NfcHelper::nfcHelperProvider(QQmlEngine */*engine*/, QJSEngine */*scrip bool NfcHelper::isAvailable() const { QNearFieldManager manager; +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) return manager.isAvailable(); +#else + return manager.isEnabled(); +#endif } diff --git a/nymea-app/nfcthingactionwriter.cpp b/nymea-app/nfcthingactionwriter.cpp index 4a13cebd..6634965e 100644 --- a/nymea-app/nfcthingactionwriter.cpp +++ b/nymea-app/nfcthingactionwriter.cpp @@ -46,7 +46,11 @@ NfcThingActionWriter::NfcThingActionWriter(QObject *parent): connect(m_actions, &RuleActions::countChanged, this, &NfcThingActionWriter::updateContent); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) m_manager->startTargetDetection(); +#else + m_manager->startTargetDetection(QNearFieldTarget::AnyAccess); +#endif } @@ -57,7 +61,11 @@ NfcThingActionWriter::~NfcThingActionWriter() bool NfcThingActionWriter::isAvailable() const { +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) return m_manager->isAvailable(); +#else + return m_manager->isEnabled(); +#endif } Engine *NfcThingActionWriter::engine() const @@ -126,11 +134,11 @@ void NfcThingActionWriter::updateContent() if (!m_engine || !m_thing) { return; } - url.setHost(m_engine->jsonRpcClient()->currentHost()->uuid().toString().remove(QRegExp("[{}]"))); + url.setHost(m_engine->jsonRpcClient()->currentHost()->uuid().toString().remove(QRegularExpression("[{}]"))); QUrlQuery query; - query.addQueryItem("t", m_thing->id().toString().remove(QRegExp("[{}]"))); + query.addQueryItem("t", m_thing->id().toString().remove(QRegularExpression("[{}]"))); for (int i = 0; i < m_actions->rowCount(); i++) { RuleAction *action = m_actions->get(i); @@ -172,17 +180,6 @@ void NfcThingActionWriter::targetDetected(QNearFieldTarget *target) { QDateTime startTime = QDateTime::currentDateTime(); qDebug() << "target detected"; - connect(target, &QNearFieldTarget::error, this, [=](QNearFieldTarget::Error error, const QNearFieldTarget::RequestId &id){ - Q_UNUSED(id) - qDebug() << "Tag error:" << error; - m_status = TagStatusFailed; - emit statusChanged(); - }); - connect(target, &QNearFieldTarget::ndefMessagesWritten, this, [=](){ - qDebug() << "Tag written in" << startTime.msecsTo(QDateTime::currentDateTime()); - m_status = TagStatusWritten; - emit statusChanged(); - }); QNearFieldTarget::RequestId m_request = target->writeNdefMessages(QList() << m_currentMessage); if (!m_request.isValid()) { @@ -191,6 +188,20 @@ void NfcThingActionWriter::targetDetected(QNearFieldTarget *target) emit statusChanged(); } + connect(target, &QNearFieldTarget::error, this, [=](QNearFieldTarget::Error error, const QNearFieldTarget::RequestId &id){ + Q_UNUSED(id) + qDebug() << "Tag error:" << error; + m_status = TagStatusFailed; + emit statusChanged(); + }); + connect(target, &QNearFieldTarget::requestCompleted, this, [=](const QNearFieldTarget::RequestId &id){ + if (id == m_request) { + qDebug() << "Tag written in" << startTime.msecsTo(QDateTime::currentDateTime()); + m_status = TagStatusWritten; + emit statusChanged(); + } + }); + m_status = TagStatusWriting; emit statusChanged(); } diff --git a/nymea-app/resources.qrc b/nymea-app/resources.qrc index 0271f7d5..5030b43d 100644 --- a/nymea-app/resources.qrc +++ b/nymea-app/resources.qrc @@ -322,5 +322,6 @@ ui/system/ServerLoggingCategoriesPage.qml ui/components/BackgroundFocusHandler.qml ui/components/LicenseInformationItem.qml + ui/shaders/coloricon.frag.qsb diff --git a/nymea-app/ui/MainPage.qml b/nymea-app/ui/MainPage.qml index 3e81459f..38303ebb 100644 --- a/nymea-app/ui/MainPage.qml +++ b/nymea-app/ui/MainPage.qml @@ -29,7 +29,7 @@ import QtQuick.Layouts 1.2 import QtQuick.Window 2.3 import Qt.labs.settings 1.0 import Qt.labs.folderlistmodel 2.2 -import QtGraphicalEffects 1.0 +import Qt5Compat.GraphicalEffects import Nymea 1.0 import "components" import "delegates" diff --git a/nymea-app/ui/components/ColorIcon.qml b/nymea-app/ui/components/ColorIcon.qml index 3fbd1674..ad60559c 100644 --- a/nymea-app/ui/components/ColorIcon.qml +++ b/nymea-app/ui/components/ColorIcon.qml @@ -23,7 +23,6 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ import QtQuick 2.4 -import QtGraphicalEffects 1.0 import Nymea 1.0 Item { @@ -72,16 +71,6 @@ Item { property color inColor: "#808080" property real threshold: 0.1 - fragmentShader: " - varying highp vec2 qt_TexCoord0; - uniform sampler2D source; - uniform highp vec4 outColor; - uniform highp vec4 inColor; - uniform lowp float threshold; - uniform lowp float qt_Opacity; - void main() { - lowp vec4 sourceColor = texture2D(source, qt_TexCoord0); - gl_FragColor = mix(vec4(outColor.rgb, 1.0) * sourceColor.a, sourceColor, step(threshold, distance(sourceColor.rgb / sourceColor.a, inColor.rgb))) * qt_Opacity; - }" + fragmentShader: "/ui/shaders/coloricon.frag.qsb" } } diff --git a/nymea-app/ui/components/MainPageTile.qml b/nymea-app/ui/components/MainPageTile.qml index 8a74179a..ecfe5d13 100644 --- a/nymea-app/ui/components/MainPageTile.qml +++ b/nymea-app/ui/components/MainPageTile.qml @@ -27,7 +27,7 @@ import QtQuick.Controls 2.2 import QtQuick.Controls.Material 2.2 import QtQuick.Layouts 1.3 import Nymea 1.0 -import QtGraphicalEffects 1.0 +import Qt5Compat.GraphicalEffects Item { id: root diff --git a/nymea-app/ui/components/MediaPlayer.qml b/nymea-app/ui/components/MediaPlayer.qml index c455f42b..ec8078ed 100644 --- a/nymea-app/ui/components/MediaPlayer.qml +++ b/nymea-app/ui/components/MediaPlayer.qml @@ -29,6 +29,7 @@ import QtQuick.Layouts 1.2 import Nymea 1.0 import NymeaApp.Utils 1.0 import QtGraphicalEffects 1.0 +import Qt5Compat.GraphicalEffects import "../delegates" import "../utils" diff --git a/nymea-app/ui/components/NymeaToolTip.qml b/nymea-app/ui/components/NymeaToolTip.qml index f9376b0b..34d31aa6 100644 --- a/nymea-app/ui/components/NymeaToolTip.qml +++ b/nymea-app/ui/components/NymeaToolTip.qml @@ -23,7 +23,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ import QtQuick 2.3 -import QtGraphicalEffects 1.0 +import Qt5Compat.GraphicalEffects import Nymea 1.0 Item { diff --git a/nymea-app/ui/mainviews/EnergyView.qml b/nymea-app/ui/mainviews/EnergyView.qml index 8b3f758d..327fb800 100644 --- a/nymea-app/ui/mainviews/EnergyView.qml +++ b/nymea-app/ui/mainviews/EnergyView.qml @@ -26,7 +26,7 @@ import QtQuick 2.8 import QtQuick.Controls 2.1 import QtQuick.Controls.Material 2.1 import QtQuick.Layouts 1.2 -import QtGraphicalEffects 1.0 +import Qt5Compat.GraphicalEffects import QtCharts 2.2 import Nymea 1.0 import "../components" diff --git a/nymea-app/ui/mainviews/energy/ConsumersBarChart.qml b/nymea-app/ui/mainviews/energy/ConsumersBarChart.qml new file mode 100644 index 00000000..02a73b17 --- /dev/null +++ b/nymea-app/ui/mainviews/energy/ConsumersBarChart.qml @@ -0,0 +1,165 @@ +import QtQuick 2.0 +import QtQuick.Layouts 1.2 +import QtQuick.Controls 2.3 +import Nymea 1.0 +import "qrc:/ui/components" + +Item { + id: root + + property EnergyManager energyManager: null + + property ThingsProxy consumers: ThingsProxy { + engine: _engine + shownInterfaces: ["smartmeterconsumer"] + } + + property var colors: null + + property int tickCount: 5 + + property int labelsWidth: 40 + + + QtObject { + id: d + property int topMargin: Style.margins + property int bottomMargin: Style.margins + property int leftMargin: Style.margins + property int rightMargin: Style.margins + } + + ColumnLayout { + anchors.fill: parent + anchors.margins: Style.smallMargins + Label { + text: qsTr("Consumers") + Layout.fillWidth: true + horizontalAlignment: Text.AlignHCenter + } + + Item { + id: valueAxis + Layout.fillWidth: true + Layout.fillHeight: true + + property double max: Math.ceil(root.energyManager.currentPowerConsumption / 100) * 100 + Repeater { + model: root.tickCount + delegate: RowLayout { + width: parent.width - d.leftMargin - d.rightMargin + y: index * ((parent.height - d.topMargin - d.bottomMargin - Style.iconSize - Style.margins) / (root.tickCount - 1)) - height / 2 + d.topMargin + x: d.leftMargin + Label { + property double value: (valueAxis.max - index * (valueAxis.max / (root.tickCount - 1))) + text: (value >= 1000 ? (value / 1000).toFixed(2) : value.toFixed(1)) + (value >= 1000 ? "kW" : "W") + font: Style.extraSmallFont + Layout.preferredWidth: root.labelsWidth + } + Rectangle { + Layout.preferredHeight: 1 + Layout.fillWidth: true + color: Style.tileOverlayColor + } + } + } + + RowLayout { + anchors.fill: parent + anchors.topMargin: d.topMargin + anchors.leftMargin: root.labelsWidth + d.leftMargin + anchors.bottomMargin: d.bottomMargin + anchors.rightMargin: d.rightMargin + + Repeater { + model: consumers.count + 1 + + delegate: ColumnLayout { + id: consumerDelegate + Layout.fillHeight: true + Layout.preferredWidth: root.width / consumers.count + spacing: Style.margins + property Thing thing: consumers.get(index) + property State currentPowerState: thing ? thing.stateByName("currentPower") : null + + property double consumption: { + var consumption = 0 + if (thing) { + consumption = currentPowerState.value + } else { + consumption = energyManager.currentPowerConsumption + for (var i = 0; i < consumers.count; i++) { + consumption -= consumers.get(i).stateByName("currentPower").value + } + } + return consumption; + } + + Item { + Layout.fillHeight: true + Layout.fillWidth: true + + Rectangle { + id: bar + anchors { + bottom: parent.bottom + horizontalCenter: parent.horizontalCenter + top: parent.top + } + gradient: Gradient { + GradientStop { position: 1; color: Style.green } + GradientStop { position: 0.5; color: Style.orange } + GradientStop { position: 0; color: Style.red } + } + width: 20 + visible: false + } + + Item { + id: barMask + anchors.fill: bar + Rectangle { + anchors { + bottom: parent.bottom + horizontalCenter: parent.horizontalCenter + } + width: 20 + Behavior on height { NumberAnimation { duration: Style.slowAnimationDuration; easing.type: Easing.InOutQuad } } + height: Math.max(1, parent.height * consumerDelegate.consumption / valueAxis.max) + // visible: false + } + } + + + OpacityMask { + anchors.fill: bar + source: bar + maskSource: barMask + } + + Label { + anchors.bottom: bar.bottom + anchors.left: bar.left + text: consumerDelegate.thing ? consumerDelegate.thing.name : qsTr("Unknown") + transform: Rotation { + angle: -90 + } + } + + } + Item { + Layout.fillWidth: true + Layout.preferredHeight: Style.iconSize + + ColorIcon { + anchors.centerIn: parent + name: consumerDelegate.thing ? app.interfacesToIcon(consumerDelegate.thing.thingClass.interfaces) : "energy" + color: root.colors[index % root.colors.length] + } + } + } + } + } + } + } +} diff --git a/nymea-app/ui/mainviews/energy/ConsumersPieChart.qml b/nymea-app/ui/mainviews/energy/ConsumersPieChart.qml index 84fc85bf..a184af1c 100644 --- a/nymea-app/ui/mainviews/energy/ConsumersPieChart.qml +++ b/nymea-app/ui/mainviews/energy/ConsumersPieChart.qml @@ -26,7 +26,6 @@ import QtQuick 2.8 import QtQuick.Controls 2.1 import QtQuick.Controls.Material 2.1 import QtQuick.Layouts 1.2 -import QtGraphicalEffects 1.0 import QtCharts 2.2 import Nymea 1.0 import NymeaApp.Utils 1.0 diff --git a/nymea-app/ui/mainviews/energy/CurrentConsumptionBalancePieChart.qml b/nymea-app/ui/mainviews/energy/CurrentConsumptionBalancePieChart.qml index 532f356c..1029f685 100644 --- a/nymea-app/ui/mainviews/energy/CurrentConsumptionBalancePieChart.qml +++ b/nymea-app/ui/mainviews/energy/CurrentConsumptionBalancePieChart.qml @@ -26,7 +26,6 @@ import QtQuick 2.8 import QtQuick.Controls 2.1 import QtQuick.Controls.Material 2.1 import QtQuick.Layouts 1.2 -import QtGraphicalEffects 1.0 import QtCharts 2.2 import Nymea 1.0 import NymeaApp.Utils 1.0 diff --git a/nymea-app/ui/mainviews/energy/CurrentProductionBalancePieChart.qml b/nymea-app/ui/mainviews/energy/CurrentProductionBalancePieChart.qml index a13c149a..b7117836 100644 --- a/nymea-app/ui/mainviews/energy/CurrentProductionBalancePieChart.qml +++ b/nymea-app/ui/mainviews/energy/CurrentProductionBalancePieChart.qml @@ -26,7 +26,6 @@ import QtQuick 2.8 import QtQuick.Controls 2.1 import QtQuick.Controls.Material 2.1 import QtQuick.Layouts 1.2 -import QtGraphicalEffects 1.0 import QtCharts 2.2 import Nymea 1.0 import NymeaApp.Utils 1.0 diff --git a/nymea-app/ui/mainviews/energy/PowerConsumptionBalanceHistory.qml b/nymea-app/ui/mainviews/energy/PowerConsumptionBalanceHistory.qml index 784d1f64..b567052b 100644 --- a/nymea-app/ui/mainviews/energy/PowerConsumptionBalanceHistory.qml +++ b/nymea-app/ui/mainviews/energy/PowerConsumptionBalanceHistory.qml @@ -25,7 +25,7 @@ import QtQuick 2.0 import QtCharts 2.2 import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 +import QtQuick.Controls 2.3 import Nymea 1.0 import "qrc:/ui/components" diff --git a/nymea-app/ui/shaders/coloricon.frag b/nymea-app/ui/shaders/coloricon.frag new file mode 100644 index 00000000..bdae5db2 --- /dev/null +++ b/nymea-app/ui/shaders/coloricon.frag @@ -0,0 +1,19 @@ +#version 440 + +layout(location = 0) in vec2 qt_TexCoord0; +layout(location = 0) out vec4 fragColor; + +layout(binding = 1) uniform sampler2D source; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + vec4 inColor; + vec4 outColor; + float threshold; +} ubuf; + +void main() { + lowp vec4 sourceColor = texture(source, qt_TexCoord0); + fragColor = mix(vec4(ubuf.outColor.rgb, 1.0) * sourceColor.a, sourceColor, step(ubuf.threshold, distance(sourceColor.rgb / sourceColor.a, ubuf.inColor.rgb))) * ubuf.qt_Opacity; +} diff --git a/nymea-app/ui/shaders/coloricon.frag.qsb b/nymea-app/ui/shaders/coloricon.frag.qsb new file mode 100644 index 0000000000000000000000000000000000000000..a3d95cb2290c09b6b7c960f87e88b6585f80f760 GIT binary patch literal 1741 zcmV;;1~T~o02bDGob6a!bJIo?-rT{2J0VHA3BpAVMmWadW}Jj3EoBBKDap{zcrr$@ zWk;9K_IK0P#3Lo0Qang9PasCB6<* z`F`e&6NIks8FRU8DiuaSyAl~&?ON(x%7CkBM|tCQRDNzpf!iratk&@D2*K5sU2&rw zg}!krdBgRV{e~Yf#BWCoQlimz;DpJ>-8S8C^lNsrU8AeV^ z$;TPU7*#inY_H;&TpZLIw^8U$5BxTrkr}cm&&ZdC3ye#c*JL-9!iK_Z2sOI7Zrz6` zE5KiK0-5xOM&Q)J4JRuB1BijGAN^V_bRx5&Gp9Glr?Bx<)jl*<@kEtBZlZd0S)EQN)6;xvo)GWonJOn{YHw=Q7tWrtfp2!* z0nM=1N$e?Jk#ktRU7}M(HBdkw(@KLc3B|+_i)Wj)njCKjI^Rnu*yUdtcvaccdQkc|B;&;OSyXxTrI-!)e~5C4_cT;9CA#k){L=I}(1$N` zDUu&29I*n?M+rlF$4TEH@t+X7#}q%(Ckey-GeXs9jP{Y9AZ!Zgv$Ti)Uxd}9j8WOp zag36#DY83Bx~61|3Y!4>3(5=HzDe{svW32%CtX9N?*hq=5&x*rz3}rQ>bp+*1nnbz zgUOrBKW*<8tA$1S`Tjk^G`&dv-i6*B6x|n5wDAWZBNQvv^)T5h0*&=KMztwYT~1N% zzXK`cJ54-@FVJiw_89gr2sNwIl%pc`(j~%I!Qy#}{}SDTd__OM1sxdI6_z87&9FLX z>?&a>y9Sof)-{r!q5aF`8|F1l@!lZcP{%CczfycRNyjYnKSOe;2lIcMV!XxlWC_!P;yVJ+FJmG6Vp^kaN^!*FSo|ko2`sZ04?vs!Am`@J~*FHTY>_Nh( zao`@6J)*E>vhk4ZJ)*rV-33;IBJJ~g9Bks=0?ApF>kRSh+%A#di!2Y13D-6HlJq-9Swff;3wzjS`eiRqy85`WY9%#TV~ ze|;v$?mpYCe>R(H1y044)V5pSZmDt=_Q0+e75;m@qI~<;hw7$Nb=%F>|A%Ypm|^*4 z6<YYKL%aZuk|iD~_t0 zj>k-^m8lg%L?Ee8Pn(+=qvCs5Xql?(vRuHRe&LXQW#Y!Hs-u2<(l3?tx0~YAhkCWW z4g^L>sN{*KAodRLqVaCG@WGR^(ql5^83@MeGb4WD_=Y3G&dQ%YBqaQ)V Date: Wed, 17 Sep 2025 15:25:31 +0200 Subject: [PATCH 02/50] Update to Qt6, introduce first cmake based build Port android to Qt 6 --- .gitmodules | 8 +- AGENTS.md | 19 + CMakeLists.txt | 94 + CMakeLists.txt.user | 701 +++ QtZeroConf | 2 +- README.md | 28 +- androidservice/androidservice.pro | 56 - androidservice/controlviews/Main.qml | 66 - androidservice/controlviews/controlviews.qrc | 5 - .../controlviews/devicecontrolapplication.cpp | 234 - .../controlviews/devicecontrolapplication.h | 37 - .../java/io/guh/nymeaapp/Action.java | 9 - .../guh/nymeaapp/NymeaAppControlService.java | 289 -- .../nymeaapp/NymeaAppControlsActivity.java | 55 - .../java/io/guh/nymeaapp/NymeaAppService.java | 50 - .../nymeaapp/NymeaAppServiceConnection.java | 283 -- .../java/io/guh/nymeaapp/NymeaHost.java | 13 - .../java/io/guh/nymeaapp/State.java | 10 - .../java/io/guh/nymeaapp/Thing.java | 56 - .../nymeaappservice/androidbinder.cpp | 115 - .../nymeaappservice/androidbinder.h | 23 - .../nymeaappservice/nymeaappservice.cpp | 83 - .../nymeaappservice/nymeaappservice.h | 27 - androidservice/service_main.cpp | 37 - config.h.in.qmake | 71 + debian | 2 +- experiences/CMakeLists.txt | 1 + experiences/airconditioning/CMakeLists.txt | 31 + .../airconditioning/airconditioning.pro | 4 +- .../airconditioningmanager.cpp | 2 - .../airconditioning/airconditioningmanager.h | 3 +- libnymea-app/CMakeLists.txt | 116 + libnymea-app/configuration/mqttpolicies.h | 8 +- .../configuration/nymeaconfiguration.h | 2 +- .../configuration/serverconfiguration.h | 2 +- .../configuration/serverconfigurations.h | 4 +- .../discovery/bluetoothservicediscovery.cpp | 15 - .../connection/discovery/nymeadiscovery.h | 1 - .../connection/discovery/upnpdiscovery.cpp | 7 +- .../discovery/zeroconfdiscovery.cpp | 16 +- .../connection/networkreachabilitymonitor.cpp | 59 +- .../connection/networkreachabilitymonitor.h | 17 +- libnymea-app/connection/nymeaconnection.cpp | 121 +- libnymea-app/connection/nymeaconnection.h | 10 +- libnymea-app/connection/nymeahosts.cpp | 3 +- libnymea-app/connection/nymeahosts.h | 69 +- .../connection/tunnelproxytransport.cpp | 2 +- libnymea-app/engine.cpp | 31 - libnymea-app/interfacesmodel.cpp | 6 +- libnymea-app/jsonrpc/jsonrpcclient.cpp | 2 +- libnymea-app/libnymea-app.pri | 1 - libnymea-app/models/boolseriesadapter.cpp | 4 +- libnymea-app/models/boolseriesadapter.h | 8 +- libnymea-app/models/newlogsmodel.cpp | 2 +- libnymea-app/models/newlogsmodel.h | 7 +- libnymea-app/models/nymeahostsfiltermodel.h | 2 +- libnymea-app/pluginconfigmanager.cpp | 2 +- libnymea-app/scripting/codecompletion.cpp | 8 +- .../serverdebug/serverdebugmanager.cpp | 2 - libnymea-app/serverdebug/serverdebugmanager.h | 9 +- libnymea-app/zigbee/zigbeenode.cpp | 3 +- libnymea-app/zwave/zwavemanager.cpp | 5 +- libnymea-app/zwave/zwavemanager.h | 21 +- libnymea-app/zwave/zwavenetwork.h | 33 +- libnymea-app/zwave/zwavenode.cpp | 7 +- nymea-app.pro | 3 - nymea-app/CMakeLists.txt | 153 + nymea-app/configuredhostsmodel.cpp | 5 +- nymea-app/main.cpp | 32 +- nymea-app/nymea-app.pro | 11 +- nymea-app/platformhelper.cpp | 3 +- .../io/guh/nymeaapp/NymeaAppActivity.java | 64 +- .../android/platformhelperandroid.cpp | 188 +- .../android/platformhelperandroid.h | 7 +- .../android/platformpermissionsandroid.cpp | 287 +- .../android/platformpermissionsandroid.h | 19 +- nymea-app/pushnotifications.cpp | 57 +- nymea-app/resources.qrc | 2 + nymea-app/styles.qrc | 1 + nymea-app/styles/dark/Background.qml | 4 +- nymea-app/styles/dark/Button.qml | 107 +- nymea-app/styles/dark/Dialog.qml | 35 +- nymea-app/styles/dark/ItemDelegate.qml | 57 + nymea-app/styles/dark/Page.qml | 6 +- nymea-app/styles/dark/Style.qml | 2 +- nymea-app/styles/energize/Background.qml | 4 +- nymea-app/styles/energize/Button.qml | 8 +- nymea-app/styles/energize/Page.qml | 4 +- nymea-app/styles/energize/Style.qml | 2 +- nymea-app/styles/light/Background.qml | 5 +- nymea-app/styles/light/Button.qml | 8 +- nymea-app/styles/light/Dialog.qml | 36 +- nymea-app/styles/light/Page.qml | 4 +- nymea-app/styles/light/Style.qml | 2 +- nymea-app/styles/lime/Background.qml | 4 +- nymea-app/styles/lime/Button.qml | 6 +- nymea-app/styles/lime/Page.qml | 4 +- nymea-app/styles/lime/Style.qml | 2 +- nymea-app/styles/mellow/Background.qml | 4 +- nymea-app/styles/mellow/Button.qml | 8 +- nymea-app/styles/mellow/Page.qml | 4 +- nymea-app/styles/mellow/Style.qml | 2 +- nymea-app/styles/noir/Background.qml | 4 +- nymea-app/styles/noir/Button.qml | 8 +- nymea-app/styles/noir/Page.qml | 6 +- nymea-app/styles/noir/Style.qml | 2 +- nymea-app/ui/Configuration.qml | 2 +- nymea-app/ui/ConfigurationBase.qml | 2 +- nymea-app/ui/KeyboardLoader.qml | 8 +- nymea-app/ui/MagicPage.qml | 17 +- nymea-app/ui/MainMenu.qml | 17 +- nymea-app/ui/MainPage.qml | 19 +- nymea-app/ui/Nymea.qml | 31 +- nymea-app/ui/PushButtonAuthPage.qml | 9 +- nymea-app/ui/RootItem.qml | 17 +- nymea-app/ui/SettingsPage.qml | 12 +- nymea-app/ui/StyleBase.qml | 2 +- nymea-app/ui/appsettings/AboutPage.qml | 11 +- nymea-app/ui/appsettings/AppLogPage.qml | 9 +- nymea-app/ui/appsettings/AppSettingsPage.qml | 11 +- .../ui/appsettings/DeveloperOptionsPage.qml | 9 +- .../ui/appsettings/LoggingCategories.qml | 9 +- .../appsettings/LookAndFeelSettingsPage.qml | 19 +- nymea-app/ui/components/ActivityIndicator.qml | 4 +- nymea-app/ui/components/AutoSizeMenu.qml | 4 +- .../ui/components/BackgroundFocusHandler.qml | 2 +- nymea-app/ui/components/BatteryStatusIcon.qml | 12 +- nymea-app/ui/components/BigThingTile.qml | 8 +- nymea-app/ui/components/BigTile.qml | 15 +- nymea-app/ui/components/BrightnessSlider.qml | 7 +- .../ui/components/BrowserContextMenu.qml | 9 +- nymea-app/ui/components/BusyOverlay.qml | 4 +- nymea-app/ui/components/ButtonControls.qml | 10 +- nymea-app/ui/components/CircleBackground.qml | 9 +- .../ui/components/ClosableArrowAnimation.qml | 4 +- .../ui/components/ClosablesControlLarge.qml | 13 +- nymea-app/ui/components/ColorIcon.qml | 4 +- nymea-app/ui/components/ColorPicker.qml | 7 +- nymea-app/ui/components/ColorPickerCt.qml | 4 +- nymea-app/ui/components/ColorPickerPre510.qml | 4 +- .../ui/components/ColorTemperaturePicker.qml | 7 +- .../ui/components/ConnectionInfoDialog.qml | 9 +- .../ui/components/ConnectionStatusIcon.qml | 6 +- nymea-app/ui/components/DatePicker.qml | 8 +- nymea-app/ui/components/Dial.qml | 9 +- .../ui/components/EmptyViewPlaceholder.qml | 8 +- nymea-app/ui/components/ErrorDialog.qml | 6 +- nymea-app/ui/components/Graph.qml | 8 +- nymea-app/ui/components/GroupedListView.qml | 4 +- nymea-app/ui/components/HeaderButton.qml | 6 +- nymea-app/ui/components/IconMenuItem.qml | 8 +- nymea-app/ui/components/Imprint.qml | 8 +- nymea-app/ui/components/InfoPane.qml | 10 +- nymea-app/ui/components/InfoPaneBase.qml | 10 +- nymea-app/ui/components/KeypadButton.qml | 10 +- nymea-app/ui/components/Led.qml | 4 +- nymea-app/ui/components/ListFilterInput.qml | 9 +- nymea-app/ui/components/ListSectionHeader.qml | 6 +- nymea-app/ui/components/MainPageTabButton.qml | 11 +- nymea-app/ui/components/MainPageTile.qml | 14 +- nymea-app/ui/components/MainViewBase.qml | 13 +- nymea-app/ui/components/MediaArtworkImage.qml | 10 +- nymea-app/ui/components/MediaBrowser.qml | 12 +- nymea-app/ui/components/MediaControls.qml | 10 +- nymea-app/ui/components/MediaPlayer.qml | 14 +- .../ui/components/MultiSelectionTabs.qml | 10 +- nymea-app/ui/components/NavigationPad.qml | 10 +- nymea-app/ui/components/NymeaDialog.qml | 26 +- nymea-app/ui/components/NymeaHeader.qml | 10 +- nymea-app/ui/components/NymeaItemDelegate.qml | 10 +- nymea-app/ui/components/NymeaSpinBox.qml | 6 +- .../ui/components/NymeaSwipeDelegate.qml | 10 +- nymea-app/ui/components/NymeaTextField.qml | 21 +- nymea-app/ui/components/NymeaToolTip.qml | 4 +- nymea-app/ui/components/PasswordTextField.qml | 8 +- nymea-app/ui/components/ProgressButton.qml | 6 +- .../ui/components/RemoveThingMethodDialog.qml | 8 +- nymea-app/ui/components/SelectionTabs.qml | 8 +- nymea-app/ui/components/SettingsPageBase.qml | 8 +- .../components/SettingsPageSectionHeader.qml | 8 +- nymea-app/ui/components/SettingsTile.qml | 8 +- nymea-app/ui/components/SetupStatusIcon.qml | 4 +- .../components/ShuffleRepeatVolumeControl.qml | 12 +- nymea-app/ui/components/ShutterControls.qml | 8 +- nymea-app/ui/components/SmartMeterChart.qml | 12 +- nymea-app/ui/components/StateDial.qml | 9 +- .../ui/components/SwipeDelegateGroup.qml | 4 +- nymea-app/ui/components/ThinDivider.qml | 6 +- nymea-app/ui/components/ThingContextMenu.qml | 8 +- nymea-app/ui/components/ThingInfoPane.qml | 10 +- nymea-app/ui/components/ThingStatusIcons.qml | 8 +- nymea-app/ui/components/ThrottledSlider.qml | 4 +- nymea-app/ui/components/TimePicker.qml | 8 +- .../ui/components/UpdateRunningOverlay.qml | 10 +- nymea-app/ui/components/UpdateStatusIcon.qml | 4 +- nymea-app/ui/components/WebViewWrapper.qml | 4 +- nymea-app/ui/components/WizardPageBase.qml | 12 +- nymea-app/ui/connection/CertificateDialog.qml | 11 +- .../ui/connection/CertificateErrorDialog.qml | 11 +- nymea-app/ui/connection/ConnectingPage.qml | 12 +- nymea-app/ui/connection/ConnectionWizard.qml | 19 +- nymea-app/ui/connection/LoginPage.qml | 13 +- .../ui/connection/ManualConnectionEntry.qml | 9 +- nymea-app/ui/connection/SetupWizard.qml | 9 +- nymea-app/ui/customviews/GarageController.qml | 11 +- nymea-app/ui/customviews/GenericTypeGraph.qml | 15 +- .../ui/customviews/GenericTypeLogView.qml | 9 +- nymea-app/ui/customviews/MultiStateChart.qml | 19 +- nymea-app/ui/customviews/SensorView.qml | 13 +- nymea-app/ui/customviews/StateChart.qml | 19 +- .../ui/customviews/ThermostatController.qml | 10 +- nymea-app/ui/customviews/WeatherView.qml | 9 +- nymea-app/ui/delegates/ActionDelegate.qml | 13 +- .../ui/delegates/BrowserItemDelegate.qml | 11 +- nymea-app/ui/delegates/InterfaceTile.qml | 13 +- nymea-app/ui/delegates/ParamDelegate.qml | 13 +- .../ui/delegates/ParamDescriptorDelegate.qml | 9 +- nymea-app/ui/delegates/SensorListDelegate.qml | 11 +- nymea-app/ui/delegates/StateDelegate.qml | 13 +- nymea-app/ui/delegates/ThingDelegate.qml | 9 +- nymea-app/ui/delegates/ThingTile.qml | 11 +- .../statedelegates/CheckboxDelegate.qml | 11 +- .../statedelegates/ColorDelegate.qml | 11 +- .../statedelegates/ComboBoxDelegate.qml | 13 +- .../statedelegates/DateTimeDelegate.qml | 11 +- .../statedelegates/LabelDelegate.qml | 11 +- .../delegates/statedelegates/LedDelegate.qml | 11 +- .../delegates/statedelegates/ListDelegate.qml | 11 +- .../statedelegates/NumberLabelDelegate.qml | 11 +- .../statedelegates/SliderDelegate.qml | 11 +- .../statedelegates/SpinBoxDelegate.qml | 11 +- .../statedelegates/SwitchDelegate.qml | 10 +- .../statedelegates/TextFieldDelegate.qml | 11 +- .../devicelistpages/AwningThingsListPage.qml | 2 +- .../devicelistpages/BlindThingsListPage.qml | 2 +- .../ClosablesThingsListPage.qml | 13 +- .../devicelistpages/GarageThingsListPage.qml | 9 +- .../devicelistpages/GenericThingsListPage.qml | 9 +- .../devicelistpages/LightThingsListPage.qml | 15 +- .../devicelistpages/MediaDeviceListPage.qml | 75 +- .../PowerSocketsDeviceListPage.qml | 11 +- .../devicelistpages/SensorsDeviceListPage.qml | 11 +- .../devicelistpages/ShutterDeviceListPage.qml | 2 +- .../SmartMeterDeviceListPage.qml | 11 +- .../ui/devicelistpages/ThingsListPageBase.qml | 13 +- .../devicelistpages/WeatherDeviceListPage.qml | 11 +- nymea-app/ui/devicepages/ActionLogPage.qml | 11 +- nymea-app/ui/devicepages/AwningThingPage.qml | 11 +- .../devicepages/BarcodeScannerThingPage.qml | 9 +- .../ui/devicepages/BoolSensorDevicePage.qml | 9 +- nymea-app/ui/devicepages/ButtonThingPage.qml | 9 +- .../ui/devicepages/CleaningRobotThingPage.qml | 11 +- nymea-app/ui/devicepages/CoolingThingPage.qml | 11 +- .../ui/devicepages/DeviceBrowserPage.qml | 9 +- .../ui/devicepages/DeviceDetailsPage.qml | 11 +- nymea-app/ui/devicepages/DeviceLogPage.qml | 11 +- .../ui/devicepages/DoorbellDevicePage.qml | 9 +- .../ui/devicepages/EvChargerThingPage.qml | 9 +- nymea-app/ui/devicepages/EventLogPage.qml | 11 +- .../FingerprintReaderDevicePage.qml | 9 +- nymea-app/ui/devicepages/GarageThingPage.qml | 11 +- nymea-app/ui/devicepages/GenericThingPage.qml | 11 +- .../ui/devicepages/HeatingDevicePage.qml | 11 +- .../ui/devicepages/InputTriggerDevicePage.qml | 9 +- .../ui/devicepages/IrrigationDevicePage.qml | 11 +- nymea-app/ui/devicepages/LightThingPage.qml | 32 +- nymea-app/ui/devicepages/MediaThingPage.qml | 13 +- .../ui/devicepages/NotificationsThingPage.qml | 9 +- .../ui/devicepages/PowersocketDevicePage.qml | 11 +- nymea-app/ui/devicepages/SensorDevicePage.qml | 13 +- .../ui/devicepages/ShutterDevicePage.qml | 13 +- .../ui/devicepages/SmartMeterDevicePage.qml | 11 +- nymea-app/ui/devicepages/StateLogPage.qml | 11 +- .../ui/devicepages/ThermostatDevicePage.qml | 11 +- nymea-app/ui/devicepages/ThingLogPage.qml | 11 +- nymea-app/ui/devicepages/ThingPageBase.qml | 9 +- nymea-app/ui/devicepages/ThingStatusPage.qml | 11 +- .../ui/devicepages/VentilationThingPage.qml | 9 +- .../ui/devicepages/WeatherDevicePage.qml | 9 +- nymea-app/ui/experiences/heating/Main.qml | 13 +- nymea-app/ui/grouping/GroupInterfacesPage.qml | 11 +- nymea-app/ui/grouping/GroupThingsPage.qml | 13 +- nymea-app/ui/magic/CalendarItemDelegate.qml | 9 +- .../ui/magic/ComposeEventDescriptorPage.qml | 9 +- nymea-app/ui/magic/EditCalendarItemPage.qml | 12 +- nymea-app/ui/magic/EditRulePage.qml | 9 +- nymea-app/ui/magic/EditStateEvaluatorPage.qml | 9 +- nymea-app/ui/magic/EditTimeEventItemPage.qml | 11 +- .../ui/magic/EventDescriptorDelegate.qml | 9 +- nymea-app/ui/magic/NewMagicPage.qml | 9 +- nymea-app/ui/magic/NewScenePage.qml | 9 +- nymea-app/ui/magic/NewThingMagicPage.qml | 9 +- nymea-app/ui/magic/RuleActionDelegate.qml | 9 +- nymea-app/ui/magic/ScriptEditor.qml | 19 +- nymea-app/ui/magic/ScriptsPage.qml | 7 +- .../ui/magic/SelectBrowserItemActionPage.qml | 7 +- .../ui/magic/SelectEventDescriptorPage.qml | 9 +- .../magic/SelectEventDescriptorParamsPage.qml | 9 +- nymea-app/ui/magic/SelectRuleActionPage.qml | 7 +- .../ui/magic/SelectRuleActionParamsPage.qml | 9 +- .../ui/magic/SelectStateDescriptorPage.qml | 7 +- .../magic/SelectStateDescriptorParamsPage.qml | 9 +- nymea-app/ui/magic/SelectStatePage.qml | 9 +- nymea-app/ui/magic/SelectThingPage.qml | 9 +- .../ui/magic/SimpleStateEvaluatorDelegate.qml | 9 +- nymea-app/ui/magic/StateEvaluatorDelegate.qml | 13 +- nymea-app/ui/magic/ThingRulesPage.qml | 9 +- nymea-app/ui/magic/TimeEventDelegate.qml | 9 +- nymea-app/ui/magic/WriteNfcTagPage.qml | 9 +- .../ui/magic/scripting/CompletionBox.qml | 9 +- nymea-app/ui/magic/scripting/EditorPane.qml | 8 +- nymea-app/ui/magic/scripting/LineNumbers.qml | 6 +- .../ui/mainviews/AirConditioningView.qml | 19 +- nymea-app/ui/mainviews/DashboardView.qml | 14 +- nymea-app/ui/mainviews/EnergyView.qml | 13 +- nymea-app/ui/mainviews/FavoritesView.qml | 13 +- nymea-app/ui/mainviews/GaragesView.qml | 9 +- nymea-app/ui/mainviews/GroupsView.qml | 11 +- nymea-app/ui/mainviews/MediaView.qml | 13 +- nymea-app/ui/mainviews/ScenesView.qml | 11 +- nymea-app/ui/mainviews/ThingsView.qml | 11 +- .../airconditioning/ACChartsPage.qml | 13 +- .../airconditioning/ACSettingsPage.qml | 11 +- .../airconditioning/BigZoneStatusIcons.qml | 13 +- .../airconditioning/EditZonePage.qml | 11 +- .../airconditioning/EditZoneThingsPage.qml | 11 +- .../airconditioning/LegendDelegate.qml | 13 +- .../TemperatureScheduleEditor.qml | 11 +- .../airconditioning/TimeOverrideDialog.qml | 13 +- .../airconditioning/TimeSchedulePage.qml | 11 +- .../airconditioning/TooltipDelegate.qml | 13 +- .../airconditioning/ZoneInfoWrapper.qml | 17 +- .../ui/mainviews/airconditioning/ZonePage.qml | 11 +- .../airconditioning/ZoneStatusIcons.qml | 9 +- .../ui/mainviews/airconditioning/ZoneView.qml | 13 +- .../mainviews/airconditioning/ZonesView.qml | 17 +- .../ui/mainviews/dashboard/Dashboard.qml | 13 +- .../dashboard/DashboardAddWizard.qml | 15 +- .../dashboard/DashboardDelegateBase.qml | 13 +- .../dashboard/DashboardFolderDelegate.qml | 15 +- .../dashboard/DashboardGraphDelegate.qml | 13 +- .../ui/mainviews/dashboard/DashboardPage.qml | 13 +- .../dashboard/DashboardSceneDelegate.qml | 13 +- .../dashboard/DashboardSensorDelegate.qml | 15 +- .../dashboard/DashboardStateDelegate.qml | 15 +- .../dashboard/DashboardThingDelegate.qml | 15 +- .../dashboard/DashboardWebViewDelegate.qml | 23 +- .../ui/mainviews/energy/ConsumerStats.qml | 13 +- .../ui/mainviews/energy/ConsumerStatsPage.qml | 9 +- .../ui/mainviews/energy/ConsumersHistory.qml | 19 +- .../mainviews/energy/ConsumersHistoryPage.qml | 9 +- .../ui/mainviews/energy/ConsumersPieChart.qml | 16 +- .../energy/ConsumersPieChartPage.qml | 9 +- .../CurrentConsumptionBalancePieChart.qml | 14 +- .../energy/CurrentPowerBalancePage.qml | 9 +- .../energy/CurrentPowerBalancePieChart.qml | 17 +- .../CurrentProductionBalancePieChart.qml | 15 +- .../mainviews/energy/EnergySettingsPage.qml | 11 +- .../mainviews/energy/PowerBalanceHistory.qml | 13 +- .../energy/PowerBalanceHistoryPage.qml | 9 +- .../ui/mainviews/energy/PowerBalanceStats.qml | 11 +- .../energy/PowerBalanceStatsPage.qml | 9 +- .../energy/PowerConsumptionBalanceHistory.qml | 11 +- .../energy/PowerProductionBalanceHistory.qml | 11 +- nymea-app/ui/mainviews/energy/StatsBase.qml | 4 +- .../ui/shaders/brightnesscircle.frag.qsb | Bin 0 -> 1868 bytes nymea-app/ui/shaders/coloricon.frag | 6 +- nymea-app/ui/shaders/coloricon.frag.qsb | Bin 1741 -> 1677 bytes nymea-app/ui/shaders/colorizedimage.frag.qsb | Bin 0 -> 1387 bytes nymea-app/ui/system/AboutNymeaPage.qml | 9 +- .../AdvancedConnectionInterfacesPage.qml | 9 +- .../ui/system/ConnectionInterfaceDelegate.qml | 9 +- .../ui/system/ConnectionInterfacesPage.qml | 9 +- nymea-app/ui/system/DeveloperTools.qml | 11 +- nymea-app/ui/system/GeneralSettingsPage.qml | 13 +- nymea-app/ui/system/LogViewerPage.qml | 16 +- nymea-app/ui/system/LogViewerPagePre18.qml | 11 +- .../ui/system/ModbusRtuAddMasterPage.qml | 19 +- .../system/ModbusRtuReconfigureMasterPage.qml | 19 +- nymea-app/ui/system/ModbusRtuSettingsPage.qml | 11 +- .../ui/system/MqttBrokerSettingsPage.qml | 9 +- nymea-app/ui/system/MqttPolicyPage.qml | 11 +- nymea-app/ui/system/NetworkSettingsPage.qml | 24 +- nymea-app/ui/system/PackageDetailsPage.qml | 11 +- nymea-app/ui/system/PackageListPage.qml | 11 +- nymea-app/ui/system/PluginParamsPage.qml | 11 +- nymea-app/ui/system/PluginsPage.qml | 11 +- .../ui/system/ServerConfigurationDialog.qml | 12 +- .../ui/system/ServerLoggingCategoriesPage.qml | 9 +- nymea-app/ui/system/SystemUpdatePage.qml | 11 +- .../TunnelProxyServerConfigurationDialog.qml | 30 +- nymea-app/ui/system/UsersSettingsPage.qml | 24 +- .../system/WebServerConfigurationDialog.qml | 12 +- nymea-app/ui/system/WebServerSettingsPage.qml | 9 +- .../WirelessNetworksFilterSettingsPage.qml | 10 +- .../ui/system/zigbee/ZigbeeAddNetworkPage.qml | 8 +- .../ui/system/zigbee/ZigbeeNetworkPage.qml | 10 +- .../zigbee/ZigbeeNetworkSettingsPage.qml | 10 +- .../zigbee/ZigbeeNetworkTopologyPage.qml | 9 +- nymea-app/ui/system/zigbee/ZigbeeNodePage.qml | 13 +- .../ui/system/zigbee/ZigbeeSettingsPage.qml | 11 +- .../ui/system/zwave/ZWaveAddNetworkPage.qml | 8 +- .../ui/system/zwave/ZWaveNetworkPage.qml | 11 +- .../system/zwave/ZWaveNetworkSettingsPage.qml | 11 +- .../ui/system/zwave/ZWaveSettingsPage.qml | 11 +- .../thingconfiguration/ConfigureThingPage.qml | 9 +- .../ui/thingconfiguration/EditThingsPage.qml | 9 +- .../ui/thingconfiguration/NewThingPage.qml | 9 +- .../ui/thingconfiguration/SetupWizard.qml | 18 +- .../ThingClassDetailsPage.qml | 9 +- nymea-app/ui/utils/ActionQueue.qml | 4 +- nymea-app/ui/utils/AirQualityIndex.qml | 5 +- nymea-app/ui/utils/NymeaUtils.qml | 7 +- packaging/android/AndroidManifest.xml | 206 +- packaging/android/build.gradle | 59 +- .../gradle/wrapper/gradle-wrapper.properties | 2 + packaging/android/res/values/libs.xml | 22 +- packaging/android/res/values/styles.xml | 6 + .../android/res/xml/qtprovider_paths.xml | 11 + packaging/ubuntu/debian-qt5/changelog | 4125 +++++++++++++++++ .../ubuntu/{debian => debian-qt5}/compat | 0 .../ubuntu/{debian => debian-qt5}/control | 0 .../ubuntu/{debian => debian-qt5}/copyright | 0 .../nymea-app-kiosk-wayland.install | 0 .../nymea-app-kiosk-wayland.postinst | 0 .../nymea-app-kiosk-x11.install | 0 .../{debian => debian-qt5}/nymea-app.install | 0 .../nymea-splashscreen.install | 0 packaging/ubuntu/{debian => debian-qt5}/rules | 0 .../ubuntu/{debian => debian-qt6}/changelog | 0 packaging/ubuntu/debian-qt6/compat | 1 + packaging/ubuntu/debian-qt6/control | 46 + .../nymea-app-kiosk-wayland.install | 2 + .../nymea-app-kiosk-wayland.postinst | 17 + .../debian-qt6/nymea-app-kiosk-x11.install | 5 + packaging/ubuntu/debian-qt6/nymea-app.install | 3 + .../debian-qt6/nymea-splashscreen.install | 2 + packaging/ubuntu/debian-qt6/rules | 10 + shared.pri | 22 +- 439 files changed, 8195 insertions(+), 3842 deletions(-) create mode 100644 AGENTS.md create mode 100644 CMakeLists.txt create mode 100644 CMakeLists.txt.user delete mode 100644 androidservice/androidservice.pro delete mode 100644 androidservice/controlviews/Main.qml delete mode 100644 androidservice/controlviews/controlviews.qrc delete mode 100644 androidservice/controlviews/devicecontrolapplication.cpp delete mode 100644 androidservice/controlviews/devicecontrolapplication.h delete mode 100644 androidservice/java/io/guh/nymeaapp/Action.java delete mode 100644 androidservice/java/io/guh/nymeaapp/NymeaAppControlService.java delete mode 100644 androidservice/java/io/guh/nymeaapp/NymeaAppControlsActivity.java delete mode 100644 androidservice/java/io/guh/nymeaapp/NymeaAppService.java delete mode 100644 androidservice/java/io/guh/nymeaapp/NymeaAppServiceConnection.java delete mode 100644 androidservice/java/io/guh/nymeaapp/NymeaHost.java delete mode 100644 androidservice/java/io/guh/nymeaapp/State.java delete mode 100644 androidservice/java/io/guh/nymeaapp/Thing.java delete mode 100644 androidservice/nymeaappservice/androidbinder.cpp delete mode 100644 androidservice/nymeaappservice/androidbinder.h delete mode 100644 androidservice/nymeaappservice/nymeaappservice.cpp delete mode 100644 androidservice/nymeaappservice/nymeaappservice.h delete mode 100644 androidservice/service_main.cpp create mode 100644 config.h.in.qmake create mode 100644 experiences/CMakeLists.txt create mode 100644 experiences/airconditioning/CMakeLists.txt create mode 100644 libnymea-app/CMakeLists.txt create mode 100644 nymea-app/CMakeLists.txt create mode 100644 nymea-app/styles/dark/ItemDelegate.qml create mode 100644 nymea-app/ui/shaders/brightnesscircle.frag.qsb create mode 100644 nymea-app/ui/shaders/colorizedimage.frag.qsb create mode 100644 packaging/android/res/values/styles.xml create mode 100644 packaging/android/res/xml/qtprovider_paths.xml create mode 100644 packaging/ubuntu/debian-qt5/changelog rename packaging/ubuntu/{debian => debian-qt5}/compat (100%) rename packaging/ubuntu/{debian => debian-qt5}/control (100%) rename packaging/ubuntu/{debian => debian-qt5}/copyright (100%) rename packaging/ubuntu/{debian => debian-qt5}/nymea-app-kiosk-wayland.install (100%) rename packaging/ubuntu/{debian => debian-qt5}/nymea-app-kiosk-wayland.postinst (100%) rename packaging/ubuntu/{debian => debian-qt5}/nymea-app-kiosk-x11.install (100%) rename packaging/ubuntu/{debian => debian-qt5}/nymea-app.install (100%) rename packaging/ubuntu/{debian => debian-qt5}/nymea-splashscreen.install (100%) rename packaging/ubuntu/{debian => debian-qt5}/rules (100%) rename packaging/ubuntu/{debian => debian-qt6}/changelog (100%) create mode 100644 packaging/ubuntu/debian-qt6/compat create mode 100644 packaging/ubuntu/debian-qt6/control create mode 100644 packaging/ubuntu/debian-qt6/nymea-app-kiosk-wayland.install create mode 100644 packaging/ubuntu/debian-qt6/nymea-app-kiosk-wayland.postinst create mode 100644 packaging/ubuntu/debian-qt6/nymea-app-kiosk-x11.install create mode 100644 packaging/ubuntu/debian-qt6/nymea-app.install create mode 100644 packaging/ubuntu/debian-qt6/nymea-splashscreen.install create mode 100755 packaging/ubuntu/debian-qt6/rules diff --git a/.gitmodules b/.gitmodules index 051dbf83..6bbdd2fa 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,11 +1,13 @@ [submodule "QtZeroConf"] path = QtZeroConf - url = https://github.com/mzanetti/QtZeroConf.git + url = https://github.com/nymea/QtZeroConf.git + branch = main [submodule "nymea-remoteproxy"] path = nymea-remoteproxy - url = https://github.com/guh/nymea-remoteproxy.git + url = https://github.com/nymea/nymea-remoteproxy.git + branch = qt6-cmake [submodule "android_openssl"] path = 3rdParty/android/android_openssl url = https://github.com/KDAB/android_openssl.git - branch = 1.0.x + branch = master shallow = true diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..95247236 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,19 @@ +# Repository Guidelines + +## Project Structure & Module Organization +`nymea-app/` holds the QtQuick entry point plus top-level QML, and `libnymea-app/` supplies shared C++ helpers, models, and logging categories. Feature bundles reside in `experiences/`, which should stay self-contained with QML, assets, and translations. Vendored code lives in `3rdParty/` and `QtZeroConf/`. Tests sit inside `tests/testrunner/` (unit) and `tests/integration/` (scenario). Packaging and store metadata are in `packaging/`, `snap/`, `debian/`, and `fastlane/`; edit them only when coordinating a release. + +## Build, Test, and Development Commands +After cloning, run `git submodule update --init --recursive`. Configure with `cmake -S . -B build -DNYMEA_ENABLE_ZEROCONF=ON` and build via `cmake --build build --target nymea-app -j$(nproc)`. Execute the suite with `cmake --build build --target test` or `ctest --test-dir build --output-on-failure`. Qt Creator users can rely on `qmake nymea-app.pro CONFIG+=withtests && make`. Re-run `messages.sh` whenever you touch translations. + +## Coding Style & Naming Conventions +Use Qt’s 4-space indentation, braces on new lines, and PascalCase for types (`DashboardModel`) with lowerCamelCase members (`defaultStyle`). Order includes as Qt, nymea, then local headers, and prefer `NYMEA_LOGGING_CATEGORY` over raw `qDebug`. In QML, match filenames to the exported component, avoid wildcard imports, and keep property names lowerCamelCase. + +## Testing Guidelines +Add Qt Test cases under `tests/testrunner/` following the module path (e.g., `tests/testrunner/dashboard/tst_dashboard.cpp`) and use descriptive names such as `shouldConnectOnValidCredentials`. Integration flows belong to `tests/integration/` and may drive nymead or device simulators. Every functional PR needs at least one automated test plus a screenshot for UI changes. Run `ctest --test-dir build -V` before requesting review and document any skipped cases. + +## Commit & Pull Request Guidelines +Commits should have concise, imperative subjects like “Fix Android packaging target configuration” plus a short body covering motivation, toggles, and tests. Pull requests must describe the issue solved, summarize design choices, link related issues, and attach test evidence (command snippets, screenshots, or APK links). Tag reviewers responsible for touched areas and keep changes scoped to a single feature or bugfix. + +## Security & Configuration Tips +Store secrets in local environment files, never in git. Update `config.h.in` or `config.pri` when adding switches and document the defaults in the PR. Android builds download OpenSSL during configuration, so ensure CI nodes have first-run network access or cache the package internally. Call out any new runtime permissions so reviewers can test them explicitly. diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..b65ad56b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,94 @@ +cmake_minimum_required(VERSION 3.16) + +file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/version.txt" NYMEA_VERSION_LINES) +list(LENGTH NYMEA_VERSION_LINES NYMEA_VERSION_COUNT) +if(NOT NYMEA_VERSION_COUNT GREATER_EQUAL 1) + message(FATAL_ERROR "version.txt must contain at least the application version") +endif() +list(GET NYMEA_VERSION_LINES 0 NYMEA_APP_VERSION) +if(NOT NYMEA_VERSION_COUNT GREATER_EQUAL 2) + set(NYMEA_APP_REVISION "0") +else() + list(GET NYMEA_VERSION_LINES 1 NYMEA_APP_REVISION) +endif() + +project(nymea-app VERSION ${NYMEA_APP_VERSION} LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +set(APPLICATION_NAME "nymea-app" CACHE STRING "Application name") +set(ORGANISATION_NAME "nymea" CACHE STRING "Organisation name") + +option(NYMEA_ENABLE_ZEROCONF "Enable ZeroConf support" OFF) +option(NYMEA_USE_MATERIAL_ICONS "Use the Material icon set instead of Suru" OFF) +option(NYMEA_ENABLE_FIREBASE "Enable Firebase Cloud Messaging integration" ON) +set(NYMEA_OVERLAY_PATH "" CACHE PATH "Optional overlay directory for branding") + +find_package(Qt6 REQUIRED COMPONENTS + Core + Gui + Network + Qml + Quick + QuickControls2 + Svg + WebSockets + Bluetooth + Charts + Nfc +) + +find_package(OpenSSL QUIET) + +if(ANDROID) + include(FetchContent) + FetchContent_Declare( + android_openssl + DOWNLOAD_EXTRACT_TIMESTAMP true + URL https://github.com/KDAB/android_openssl/archive/refs/heads/master.zip + ) + FetchContent_MakeAvailable(android_openssl) + include(${android_openssl_SOURCE_DIR}/android_openssl.cmake) + + set(NYMEA_ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_SOURCE_DIR}/packaging/android" CACHE PATH "Android packaging directory") + + set(_nymea_app_root_property "nymeaAppRoot=${CMAKE_SOURCE_DIR}") + if(NYMEA_ENABLE_FIREBASE) + set(_nymea_firebase_property "useFirebase=true") + else() + set(_nymea_firebase_property "useFirebase=false") + endif() + + file(WRITE "${NYMEA_ANDROID_PACKAGE_SOURCE_DIR}/nymeaapp.properties" "${_nymea_app_root_property}\n${_nymea_firebase_property}\n") + configure_file( + "${CMAKE_SOURCE_DIR}/version.txt" + "${NYMEA_ANDROID_PACKAGE_SOURCE_DIR}/version.txt" + COPYONLY + ) + + add_link_options("-Wl,-z,max-page-size=16384") +endif() + +# Make config.h available to all targets +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_BINARY_DIR}/config.h @ONLY) + +# Common warning flags +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + add_compile_options(-Wall) + if(UNIX AND NOT APPLE) + add_compile_options(-Wno-deprecated-declarations -Wno-deprecated-copy) + endif() +endif() + +set(APP_VERSION ${NYMEA_APP_VERSION}) +set(APP_REVISION ${NYMEA_APP_REVISION}) + +add_subdirectory(libnymea-app) +add_subdirectory(experiences) +add_subdirectory(nymea-app) diff --git a/CMakeLists.txt.user b/CMakeLists.txt.user new file mode 100644 index 00000000..a7dea20a --- /dev/null +++ b/CMakeLists.txt.user @@ -0,0 +1,701 @@ + + + + + + EnvironmentId + {3a02a921-eea1-43cd-a37d-2b4e59d6151d} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + true + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 0 + 80 + true + true + 1 + 0 + false + true + false + 2 + true + true + 0 + 8 + true + false + 1 + true + true + true + *.md, *.MD, Makefile + false + true + true + + + + ProjectExplorer.Project.PluginSettings + + + true + false + true + true + true + true + + false + + + 0 + true + + true + true + Builtin.DefaultTidyAndClazy + 10 + true + + + + true + + 0 + + + + ProjectExplorer.Project.Target.0 + + Android.Device.Type + true + Android Qt 6.8.4 Clang armeabi-v7a + Android Qt 6.8.4 Clang armeabi-v7a + {4ea481fa-d782-4c19-8a79-381a58bbab97} + 0 + 0 + 0 + + Debug + 2 + false + + -DQT_HOST_PATH:PATH=%{Qt:QT_HOST_PREFIX} +-DANDROID_PLATFORM:STRING=android-23 +-DANDROID_SDK_ROOT:PATH=/usr/local/android +-DQT_USE_TARGET_ANDROID_BUILD_DIR:BOOL=ON +-DANDROID_USE_LEGACY_TOOLCHAIN_FILE:BOOL=OFF +-DCMAKE_BUILD_TYPE:STRING=Debug +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DQT_NO_GLOBAL_APK_TARGET_PART_OF_ALL:BOOL=ON +-DANDROID_ABI:STRING=armeabi-v7a +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DQT_MAINTENANCE_TOOL:FILEPATH=/home/timon/Qt/MaintenanceTool +-DANDROID_NDK:PATH=/usr/local/android/ndk/26.1.10909125 +-DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_FIND_ROOT_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DANDROID_STL:STRING=c++_shared +-DCMAKE_TOOLCHAIN_FILE:FILEPATH=/usr/local/android/ndk/26.1.10909125/build/cmake/android.toolchain.cmake + 0 + /home/timon/nymea/development/qt6-cmake/nymea-app/build/Android_Qt_6_8_4_Clang_armeabi_v7a-Debug + + + + + all + + false + + true + Build + CMakeProjectManager.MakeStep + + + android-36 + + + true + Build Android APK + QmakeProjectManager.AndroidBuildApkStep + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + + clean + + false + + true + Build + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Debug + CMakeProjectManager.CMakeBuildConfiguration + 0 + 0 + + + + true + Qt4ProjectManager.AndroidDeployQtStep + + 1 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + Qt4ProjectManager.AndroidDeployConfiguration2 + + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 2 + + true + + arm64-v8a + armeabi-v7a + armeabi + + 0A301JEC211655 + 33 + + true + + + true + true + 0 + true + + + + + + + + 0 + + false + -e cpu-cycles --call-graph dwarf,4096 -F 250 + nymea-app + Qt4ProjectManager.AndroidRunConfiguration: + nymea-app + true + + true + true + + 1 + + 1 + + + + true + Qt4ProjectManager.AndroidDeployQtStep + + 1 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + Qt4ProjectManager.AndroidDeployConfiguration2 + + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 2 + + true + true + 0 + true + + + + + + + + 0 + + false + -e cpu-cycles --call-graph dwarf,4096 -F 250 + nymea-app + Qt4ProjectManager.AndroidRunConfiguration: + nymea-app + true + + true + true + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop + true + Desktop Qt 6.8.4 + Desktop Qt 6.8.4 + qt.qt6.684.linux_gcc_64_kit + 0 + 0 + 0 + + Debug + 2 + false + + -DCMAKE_BUILD_TYPE:STRING=Debug +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DQT_MAINTENANCE_TOOL:FILEPATH=/home/timon/Qt/MaintenanceTool +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} + 0 + /home/timon/nymea/development/qt6-cmake/nymea-app/build/Desktop_Qt_6_8_4-Debug + + + + + all + + false + + true + Build + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + + clean + + false + + true + Build + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Debug + CMakeProjectManager.CMakeBuildConfiguration + 0 + 0 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + + + + + + + + false + + true + ApplicationManagerPlugin.Deploy.CMakePackageStep + + + install-package --acknowledge + true + Install Application Manager package + ApplicationManagerPlugin.Deploy.InstallPackageStep + + + + + + + + 2 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ApplicationManagerPlugin.Deploy.Configuration + + 2 + + true + true + 0 + true + + 2 + + false + -e cpu-cycles --call-graph dwarf,4096 -F 250 + nymea-app + CMakeProjectManager.CMakeRunConfiguration. + nymea-app + true + + true + true + true + false + + 1 + + 1 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + + + + + + + + false + + true + ApplicationManagerPlugin.Deploy.CMakePackageStep + + + install-package --acknowledge + true + Install Application Manager package + ApplicationManagerPlugin.Deploy.InstallPackageStep + + + + + + + + 2 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ApplicationManagerPlugin.Deploy.Configuration + + 2 + + true + true + 0 + true + + 2 + + false + -e cpu-cycles --call-graph dwarf,4096 -F 250 + nymea-app + CMakeProjectManager.CMakeRunConfiguration. + nymea-app + true + + true + true + true + false + + 1 + + + + ProjectExplorer.Project.Target.2 + + Android.Device.Type + true + Android Qt 6.8.4 Clang armeabi-v7a + Android Qt 6.8.4 Clang armeabi-v7a + {d6a68c9e-38a8-48ba-9f70-7050ff8c051f} + 0 + 0 + 0 + + Debug + 2 + false + + -DANDROID_STL:STRING=c++_shared +-DQT_NO_GLOBAL_APK_TARGET_PART_OF_ALL:BOOL=ON +-DQT_HOST_PATH:PATH=%{Qt:QT_HOST_PREFIX} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DANDROID_ABI:STRING=armeabi-v7a +-DCMAKE_BUILD_TYPE:STRING=Debug +-DANDROID_NDK:PATH=/usr/local/android/ndk/29.0.14033849 +-DQT_USE_TARGET_ANDROID_BUILD_DIR:BOOL=ON +-DANDROID_USE_LEGACY_TOOLCHAIN_FILE:BOOL=OFF +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_FIND_ROOT_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DANDROID_SDK_ROOT:PATH=/usr/local/android +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DANDROID_PLATFORM:STRING=android-23 +-DQT_MAINTENANCE_TOOL:FILEPATH=/home/timon/Qt/MaintenanceTool +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_TOOLCHAIN_FILE:FILEPATH=/usr/local/android/ndk/29.0.14033849/build/cmake/android.toolchain.cmake +-DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} + 0 + /home/timon/nymea/development/qt6-cmake/nymea-app/build/Android_Qt_6_8_4_Clang_armeabi_v7a-Debug + + + + + all + + false + + true + Build + CMakeProjectManager.MakeStep + + + android-36 + + + true + Build Android APK + QmakeProjectManager.AndroidBuildApkStep + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + + clean + + false + + true + Build + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Debug + CMakeProjectManager.CMakeBuildConfiguration + 0 + 0 + + + + true + Qt4ProjectManager.AndroidDeployQtStep + + 1 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + Qt4ProjectManager.AndroidDeployConfiguration2 + + 1 + + true + true + 0 + true + + + + + + + + 0 + + false + -e cpu-cycles --call-graph dwarf,4096 -F 250 + nymea-app + Qt4ProjectManager.AndroidRunConfiguration: + nymea-app + false + true + true + + 1 + + 1 + + + + true + Qt4ProjectManager.AndroidDeployQtStep + + 1 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + Qt4ProjectManager.AndroidDeployConfiguration2 + + 1 + + true + true + 0 + true + + + + + + + + 0 + + false + -e cpu-cycles --call-graph dwarf,4096 -F 250 + nymea-app + Qt4ProjectManager.AndroidRunConfiguration: + nymea-app + false + true + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 3 + + + Version + 22 + + diff --git a/QtZeroConf b/QtZeroConf index 2b9b3c7c..6e70786e 160000 --- a/QtZeroConf +++ b/QtZeroConf @@ -1 +1 @@ -Subproject commit 2b9b3c7c74f05e83c4052fbb1629b22568f36b64 +Subproject commit 6e70786eef77303b5d630ce4acc7c49e03a58992 diff --git a/README.md b/README.md index b09f8880..48c05123 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ QtQuick nymea client application # building Required packages: -It is recommended to install a complete Qt installation. Minimum required Qt Version *5.7.0*. +It is recommended to install a complete Qt installation. Minimum required Qt version is Qt 6. No extra modules are required for a basic desktop build. @@ -14,14 +14,19 @@ After cloning the repository, run $ git submodule init $ git submodule update -To build a binary run +To build a binary with CMake run - $ mkdir builddir - $ cd builddir - $ qmake path/to/source/dir - $ make + $ cmake -S . -B build + $ cmake --build build -Or open `nymea-app.pro` in QtCreator and click the **"Play"** button. +The build can be customised with the following cache variables: + +- `-DNYMEA_ENABLE_ZEROCONF=ON` enables ZeroConf support when the QtZeroConf and + Avahi dependencies are available. +- `-DNYMEA_USE_MATERIAL_ICONS=ON` switches the icon theme to the Material icon set. + +Legacy qmake builds are still available by opening `nymea-app.pro` in QtCreator +and building the project there. Optional configuration flags to be passed to qmake: @@ -30,8 +35,13 @@ Optional configuration flags to be passed to qmake: > Enables building the testrunner target ## Android -As Qt can't bundle a build of openssl for android, you need to place a copy to -`/opt/android-ssl/` +When targeting Android, the build will download the KDAB +[`android_openssl`](https://github.com/KDAB/android_openssl) package at +configure time and automatically bundle the provided `libssl` and `libcrypto` +shared libraries inside the APK. An active internet connection is therefore +required the first time you configure an Android build directory. Other +platforms will build without explicitly linking to OpenSSL if the development +package is not installed. ## Windows diff --git a/androidservice/androidservice.pro b/androidservice/androidservice.pro deleted file mode 100644 index 7503e717..00000000 --- a/androidservice/androidservice.pro +++ /dev/null @@ -1,56 +0,0 @@ -TEMPLATE = lib -TARGET = service -CONFIG += dll -QT += core androidextras -QT += network qml quick quickcontrols2 svg websockets bluetooth charts nfc - -include(../shared.pri) -include(../3rdParty/android/android_openssl/openssl.pri) - - -INCLUDEPATH += $$top_srcdir/libnymea-app/ - -# https://bugreports.qt.io/browse/QTBUG-83165 -LIBS += -L$${top_builddir}/libnymea-app/$${ANDROID_TARGET_ARCH} - -LIBS += -L$$top_builddir/libnymea-app/ -lnymea-app -PRE_TARGETDEPS += ../libnymea-app - -RESOURCES += controlviews/controlviews.qrc \ - ../nymea-app/resources.qrc \ - ../nymea-app/images.qrc \ - ../nymea-app/styles.qrc - -INCLUDEPATH += ../nymea-app/ - -SOURCES += \ - controlviews/devicecontrolapplication.cpp \ - nymeaappservice/nymeaappservice.cpp \ - nymeaappservice/androidbinder.cpp \ - ../nymea-app/stylecontroller.cpp \ - ../nymea-app/platformhelper.cpp \ - ../nymea-app/nfchelper.cpp \ - ../nymea-app/nfcthingactionwriter.cpp \ - ../nymea-app/platformintegration/android/platformhelperandroid.cpp \ - service_main.cpp - -HEADERS += \ - controlviews/devicecontrolapplication.h \ - nymeaappservice/nymeaappservice.h \ - nymeaappservice/androidbinder.h \ - ../nymea-app/stylecontroller.h \ - ../nymea-app/platformhelper.h \ - ../nymea-app/nfchelper.h \ - ../nymea-app/nfcthingactionwriter.h \ - ../nymea-app/platformintegration/android/platformhelperandroid.h \ - -DISTFILES += \ - java/io/guh/nymeaapp/Action.java \ - java/io/guh/nymeaapp/NymeaAppControlService.java \ - java/io/guh/nymeaapp/NymeaAppService.java \ - java/io/guh/nymeaapp/NymeaAppControlsActivity.java \ - java/io/guh/nymeaapp/NymeaAppServiceConnection.java \ - java/io/guh/nymeaapp/Thing.java \ - java/io/guh/nymeaapp/State.java \ - java/io/guh/nymeaapp/NymeaHost.java \ - controlviews/Main.qml diff --git a/androidservice/controlviews/Main.qml b/androidservice/controlviews/Main.qml deleted file mode 100644 index 68a355c2..00000000 --- a/androidservice/controlviews/Main.qml +++ /dev/null @@ -1,66 +0,0 @@ -import QtQuick 2.8 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import Qt.labs.settings 1.0 -import Nymea 1.0 -import "qrc:/ui/devicepages/" - -ApplicationWindow { - id: app - visible: true - visibility: ApplicationWindow.FullScreen - color: Material.background - title: Configuration.appName - - Material.theme: NymeaUtils.isDark(Style.backgroundColor) ? Material.Dark : Material.Light - Material.background: Style.backgroundColor - Material.accent: Style.accentColor - Material.foreground: Style.foregroundColor - - font.pixelSize: mediumFont - font.weight: Font.Normal - font.capitalization: Font.MixedCase - font.family: Style.fontFamily - - property int margins: 16 - property int bigMargins: 20 - - property int extraSmallFont: 10 - property int smallFont: 13 - property int mediumFont: 16 - property int largeFont: 20 - - property int smallIconSize: 16 - property int iconSize: 24 - property int bigIconSize: 40 - property int hugeIconSize: 64 - - property int delegateHeight: 60 - - readonly property bool landscape: app.width > app.height - - ThingsProxy { - id: thingProxy - engine: _engine - filterThingId: controlledThingId - } - - property Thing controlledThing: engine.thingManager.fetchingData ? null : engine.thingManager.things.getThing(controlledThingId) - - onControlledThingChanged: { - loader.setSource("qrc:/ui/devicepages/" + NymeaUtils.interfaceListToDevicePage(controlledThing.thingClass.interfaces), {thing: controlledThing, header: null}) - PlatformHelper.hideSplashScreen(); - } - - Loader { - id: loader - anchors.fill: parent - anchors.bottomMargin: app.margins // For some reason the bottom edge seems a bit off in the overlay - } - - onClosing: { - print("************* Control View closing") - } - -} diff --git a/androidservice/controlviews/controlviews.qrc b/androidservice/controlviews/controlviews.qrc deleted file mode 100644 index f907b18e..00000000 --- a/androidservice/controlviews/controlviews.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - Main.qml - - diff --git a/androidservice/controlviews/devicecontrolapplication.cpp b/androidservice/controlviews/devicecontrolapplication.cpp deleted file mode 100644 index 67d16dfd..00000000 --- a/androidservice/controlviews/devicecontrolapplication.cpp +++ /dev/null @@ -1,234 +0,0 @@ -#include "devicecontrolapplication.h" - -#include "engine.h" -#include "connection/discovery/nymeadiscovery.h" -#include "connection/nymeahosts.h" -#include "libnymea-app-core.h" -#include "../nymea-app/stylecontroller.h" -#include "../nymea-app/platformhelper.h" -#include "../nymea-app/nfchelper.h" -#include "../nymea-app/nfcthingactionwriter.h" -#include "../nymea-app/platformintegration/android/platformhelperandroid.h" - -#include -#include -#include -#include -#include -#include -#include - -QObject *platformHelperProvider(QQmlEngine *engine, QJSEngine *scriptEngine) -{ - Q_UNUSED(engine) - Q_UNUSED(scriptEngine) - return new PlatformHelperAndroid(); -} - -DeviceControlApplication::DeviceControlApplication(int argc, char *argv[]) : QApplication(argc, argv) -{ - setApplicationName("nymea-app"); - setOrganizationName("nymea"); - - QSettings settings; - - m_discovery = new NymeaDiscovery(this); - - m_engine = new Engine(this); - - m_qmlEngine = new QQmlApplicationEngine(this); - - Nymea::Core::registerQmlTypes(); - - qmlRegisterSingletonType("Nymea", 1, 0, "PlatformHelper", platformHelperProvider); - qmlRegisterSingletonType(QUrl("qrc:///ui/utils/NymeaUtils.qml"), "Nymea", 1, 0, "NymeaUtils" ); - qmlRegisterType("Nymea", 1, 0, "NfcThingActionWriter"); - qmlRegisterSingletonType("Nymea", 1, 0, "NfcHelper", NfcHelper::nfcHelperProvider); - - StyleController *styleController = new StyleController("light", this); - - QQmlFileSelector *styleSelector = new QQmlFileSelector(m_qmlEngine); - styleSelector->setExtraSelectors({styleController->currentStyle()}); - - foreach (const QFileInfo &fi, QDir(":/ui/fonts/").entryInfoList()) { - QFontDatabase::addApplicationFont(fi.absoluteFilePath()); - } - foreach (const QFileInfo &fi, QDir(":/styles/" + styleController->currentStyle() + "/fonts/").entryInfoList()) { - qDebug() << "Adding style font:" << fi.absoluteFilePath(); - QFontDatabase::addApplicationFont(fi.absoluteFilePath()); - } - - qmlRegisterSingletonType(QUrl("qrc:///styles/" + styleController->currentStyle() + "/Style.qml"), "Nymea", 1, 0, "Style" ); - - m_qmlEngine->rootContext()->setContextProperty("styleController", styleController); - m_qmlEngine->rootContext()->setContextProperty("engine", m_engine); - m_qmlEngine->rootContext()->setContextProperty("_engine", m_engine); - m_qmlEngine->rootContext()->setContextProperty("controlledThingId", ""); // Unknown at this point - - m_qmlEngine->load(QUrl(QLatin1String("qrc:/Main.qml"))); - - jboolean startedByNfc = QtAndroid::androidActivity().callMethod("startedByNfc", "()Z"); - if (startedByNfc) { - qDebug() << "**** Started by NFC"; - qDebug() << "Registering NFC handler and waiting for message."; - - QNearFieldManager *manager = new QNearFieldManager(this); - manager->registerNdefMessageHandler(this, SLOT(handleNdefMessage(QNdefMessage,QNearFieldTarget*))); - - } else { - qDebug() << "*** Started by other intent"; - qDebug() << "Expecing nymeaId and thingId in intent extras."; - QString nymeaId = QtAndroid::androidActivity().callObjectMethod("nymeaId").toString(); - QString thingId = QtAndroid::androidActivity().callObjectMethod("thingId").toString(); - - connectToNymea(nymeaId); - m_qmlEngine->rootContext()->setContextProperty("controlledThingId", thingId); - } -} - -void DeviceControlApplication::handleNdefMessage(QNdefMessage message, QNearFieldTarget *target) -{ - Q_UNUSED(target) - qDebug() << "************* NFC message!" << message.toByteArray(); - if (message.count() < 1) { - qWarning() << "NFC message doesn't contain any records..."; - return; - } - // NOTE: At this point we're only supporting one NDEF record per message - QNdefRecord record = message.first(); - QNdefNfcUriRecord uriRecord(record); - - QUrl url = uriRecord.uri(); - if (url.scheme() != "nymea") { - qWarning() << "NDEF URI record scheme is not \"nymea://\""; - return; - } - - QUuid nymeaId = QUuid(url.host()); - if (nymeaId.isNull()) { - qWarning() << "Invalid nymea UUID in NDEF record."; - return; - } - - QUuid thingId = QUuid(QUrlQuery(url).queryItemValue("t")); - if (thingId.isNull()) { - qWarning() << "Invalid thing in NDEF record"; - return; - } - - m_pendingNfcAction = url; - - connectToNymea(nymeaId); - m_qmlEngine->rootContext()->setContextProperty("controlledThingId", thingId); - - connect(m_engine->thingManager(), &ThingManager::fetchingDataChanged, [this](){ - if (m_engine->jsonRpcClient()->connected() && !m_engine->thingManager()->fetchingData()) { - qDebug() << "Ready to process commands"; - runNfcAction(); - } - }); -} - -void DeviceControlApplication::connectToNymea(const QUuid &nymeaId) -{ - NymeaHost *host = m_discovery->nymeaHosts()->find(nymeaId); - if (!host) { - qWarning() << "No such nymea host:" << nymeaId; - // TODO: We could wait here until the discovery finds it... But it really should be cached already... - exit(1); - } - qDebug() << "Connecting to:" << host->name(); - m_engine->jsonRpcClient()->connectToHost(host); -} - -void DeviceControlApplication::runNfcAction() -{ - if (!m_pendingNfcAction.isEmpty()) { - qDebug() << "NFC action:" << m_pendingNfcAction; - } - QUrl url = m_pendingNfcAction; - m_pendingNfcAction.clear(); - - if (url.scheme() != "nymea") { - qWarning() << "NDEF URI record scheme is not \"nymea://\" in" << url.toString(); - return; - } - - QUuid nymeaId = QUuid(url.host()); - if (nymeaId.isNull()) { - qWarning() << "Invalid nymea UUID" << url.host() << "in NDEF record" << url.toString(); - return; - } - - QUuid thingId = QUuid(QUrlQuery(url).queryItemValue("t")); - Thing *thing = m_engine->thingManager()->things()->getThing(thingId); - if (!thing) { - qDebug() << "Thing" << thingId.toString() << "from" << url.toString() << "doesn't exist on nymea host" << nymeaId.toString(); - return; - } - - QList> queryItems = QUrlQuery(url.query()).queryItems(); - for (int i = 0; i < queryItems.count(); i++) { - QString entryName = queryItems.at(i).first; - if (entryName == "t") { - continue; - } - if (!entryName.startsWith("a")) { - qDebug() << "Only actions are supported. Skipping query item" << entryName; - continue; - } - - QString actionString = queryItems.at(i).second; - QStringList parts = actionString.split("#"); - if (parts.count() == 0) { - qDebug() << "Invalid action definition:" << actionString; - continue; - } - - if (parts.count() > 2) { - // The parameters might contain a #, let's merge them again - parts[1] = parts.mid(1).join('#'); - } - - QString actionTypeName = parts.at(0); - ActionType *actionType = thing->thingClass()->actionTypes()->findByName(actionTypeName); - if (!actionType) { - qWarning() << "Invalid action name" << actionType << "in url:" << url.toString(); - continue; - } - - QHash paramsInUri; - if (parts.count() > 1) { - QString paramsString = parts.at(1); - foreach (const QString ¶mString, paramsString.split("+")) { - QStringList parts = paramString.split(":"); - if (parts.count() != 2) { - qWarning() << "Invalid param format" << paramString << "in url:" << url.toString(); - continue; - } - paramsInUri.insert(parts.at(0), parts.at(1)); - } - } - - qDebug() << "Parameters in NFC uri:" << paramsInUri; - - QVariantList params; - for (int j = 0; j < actionType->paramTypes()->rowCount(); j++) { - ParamType *paramType = actionType->paramTypes()->get(j); - QVariantMap param; - param.insert("paramTypeId", paramType->id()); - if (paramsInUri.contains(paramType->name())) { - param.insert("value", paramsInUri.value(paramType->name())); - } else { - param.insert("value", paramType->defaultValue()); - } - params.append(param); - } - - qDebug() << "Action parameters:" << qUtf8Printable(QJsonDocument::fromVariant(params).toJson()); - - m_engine->thingManager()->executeAction(thingId, actionType->id(), params); - } -} - - diff --git a/androidservice/controlviews/devicecontrolapplication.h b/androidservice/controlviews/devicecontrolapplication.h deleted file mode 100644 index edd6985c..00000000 --- a/androidservice/controlviews/devicecontrolapplication.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef DEVICECONTROLAPPLICATION_H -#define DEVICECONTROLAPPLICATION_H - -#include -#include -#include -#include -#include - -#include "types/ruleactions.h" -#include "connection/discovery/nymeadiscovery.h" -#include "engine.h" - -class DeviceControlApplication : public QApplication -{ - Q_OBJECT -public: - explicit DeviceControlApplication(int argc, char *argv[]); - -private slots: - void handleNdefMessage(QNdefMessage message,QNearFieldTarget* target); - - void connectToNymea(const QUuid &nymeaId); - - void runNfcAction(); - -private: - NymeaDiscovery *m_discovery = nullptr; - Engine *m_engine = nullptr; - QQmlApplicationEngine *m_qmlEngine = nullptr; - - QUrl m_pendingNfcAction; - - -}; - -#endif // DEVICECONTROLAPPLICATION_H diff --git a/androidservice/java/io/guh/nymeaapp/Action.java b/androidservice/java/io/guh/nymeaapp/Action.java deleted file mode 100644 index 04923f02..00000000 --- a/androidservice/java/io/guh/nymeaapp/Action.java +++ /dev/null @@ -1,9 +0,0 @@ -package io.guh.nymeaapp; - -import java.util.UUID; - -public class Action { - public UUID typeId; - public String name; - public String displayName; -} diff --git a/androidservice/java/io/guh/nymeaapp/NymeaAppControlService.java b/androidservice/java/io/guh/nymeaapp/NymeaAppControlService.java deleted file mode 100644 index 8d3a7e0d..00000000 --- a/androidservice/java/io/guh/nymeaapp/NymeaAppControlService.java +++ /dev/null @@ -1,289 +0,0 @@ -package io.guh.nymeaapp; - -import android.util.Log; -import android.content.Intent; -import android.content.ServiceConnection; -import android.content.ComponentName; -import android.app.PendingIntent; -import android.net.Uri; -import android.content.Context; -import android.service.controls.ControlsProviderService; -import android.service.controls.actions.*; -import android.service.controls.Control; -import android.service.controls.DeviceTypes; -import android.service.controls.templates.*; -import android.os.Binder; -import android.os.IBinder; -import android.os.Parcel; - -import java.util.concurrent.Flow.Publisher; -import java.util.function.Consumer; -import java.util.List; -import java.util.ArrayList; -import java.util.UUID; -import java.util.HashMap; -import io.reactivex.Flowable; -import io.reactivex.processors.ReplayProcessor; -import org.reactivestreams.FlowAdapters; -import org.json.*; - -// Android device controls service - -// This service is instantiated by the android device controls on demand. It will -// connect to the NymeaAppService and interact with nymea through that. - -public class NymeaAppControlService extends ControlsProviderService { - private String TAG = "nymea-app: NymeaAppControlService"; - private NymeaAppServiceConnection m_serviceConnection; - - // For publishing all available - private ReplayProcessor m_publisherForAll; - private ArrayList m_pendingForAll = new ArrayList(); // pending nymea ids to query - - private ReplayProcessor m_updatePublisher; - private List m_activeControlIds; - - - private void ensureServiceConnection() { - if (m_serviceConnection == null) { - m_serviceConnection = new NymeaAppServiceConnection(getBaseContext()) { - @Override public void onConnectedChanged(boolean connected) { - Log.d(TAG, "Connected to NymeaAppService. Known hosts: " + m_serviceConnection.getHosts().size()); - if (connected && m_publisherForAll != null) { - Log.d(TAG, "Processing all"); - processAll(); - } - } - @Override public void onReadyChanged(UUID nymeaId, boolean ready) { - Log.d(TAG, "Nymea instance " + nymeaId.toString() + " ready state changed: " + Boolean.toString(ready)); - if (ready) { - process(nymeaId); - } - } - @Override public void onUpdate(UUID nymeaId, UUID thingId) { - if (m_updatePublisher != null && m_activeControlIds.contains(thingId.toString())) { -// Log.d(TAG, "Updating publisher for thing: " + thingId); - m_updatePublisher.onNext(thingToControl(nymeaId, thingId)); -// m_updatePublisher.onComplete(); - } - } - }; - } - Intent serviceIntent = new Intent(this, NymeaAppService.class); - bindService(serviceIntent, m_serviceConnection, Context.BIND_AUTO_CREATE); - } - - private void processAll() { - ensureServiceConnection(); - if (m_serviceConnection.connected()) { - // Need to add all the pending before processing - if (m_publisherForAll != null) { - for (UUID nymeaId: m_serviceConnection.getHosts().keySet()) { - m_pendingForAll.add(nymeaId); - } - } - for (UUID nymeaId: m_serviceConnection.getHosts().keySet()) { - if (m_serviceConnection.getHosts().get(nymeaId).isReady) { - process(nymeaId); - } - } - } else { - Log.d(TAG, "Not connected to NymeaAppService yet..."); - } - } - - private void process(UUID nymeaId) { - Log.d(TAG, "Processing..."); - ensureServiceConnection(); - if (!m_serviceConnection.connected()) { - Log.d(TAG, "NymeaAppService not connected to nymea instance " + nymeaId + " yet."); - return; - } - if (!m_serviceConnection.getHosts().keySet().contains(nymeaId)) { - Log.d(TAG, "Service connection is not ready yet..."); - return; - } - - for (Thing thing : m_serviceConnection.getHosts().get(nymeaId).things.values()) { - Log.d(TAG, "Processing thing: " + thing.name); - - if (m_publisherForAll != null) { - Log.d(TAG, "Adding stateless"); - m_publisherForAll.onNext(thingToControl(nymeaId, thing.id)); - } - - if (m_updatePublisher != null) { - if (m_activeControlIds.contains(thing.id.toString())) { - Log.d(TAG, "Adding stateful"); - m_updatePublisher.onNext(thingToControl(nymeaId, thing.id)); - } - } - } - - if (m_pendingForAll.contains(nymeaId)) { - m_pendingForAll.remove(nymeaId); - } - - // The publisher for all needs to be completed when done - if (m_publisherForAll != null && m_pendingForAll.isEmpty()) { - Log.d(TAG, "Completing all publisher"); - m_publisherForAll.onComplete(); - } - - Log.d(TAG, "Done processing"); - // We never close the update publisher as we need that one to send updates - } - - - @Override - public Publisher createPublisherForAllAvailable() { - Log.d(TAG, "Creating publishers for all"); - m_publisherForAll = ReplayProcessor.create(); - processAll(); - return FlowAdapters.toFlowPublisher(m_publisherForAll); - } - - @Override - public Publisher createPublisherFor(List controlIds) { - Log.d(TAG, "Creating publishers for " + Integer.toString(controlIds.size())); - m_updatePublisher = ReplayProcessor.create(); - m_activeControlIds = controlIds; - processAll(); - return FlowAdapters.toFlowPublisher(m_updatePublisher); - } - - @Override - public void performControlAction(String controlId, ControlAction action, Consumer consumer) { - Log.d(TAG, "Performing control action: " + controlId); - - UUID nymeaId = m_serviceConnection.hostForThing(UUID.fromString(controlId)); - if (nymeaId == null) { - Log.d(TAG, "Nymea host not found for thing id: " + controlId); - consumer.accept(ControlAction.RESPONSE_FAIL); - return; - } - Thing thing = m_serviceConnection.getThing(UUID.fromString(controlId)); - if (thing == null) { - Log.d(TAG, "Thing not found for id: " + controlId); - consumer.accept(ControlAction.RESPONSE_FAIL); - return; - } - - UUID actionTypeId; - String param; - if (thing.interfaces.contains("dimmablelight") && action instanceof FloatAction) { - actionTypeId = thing.stateByName("brightness").typeId; - FloatAction fAction = (FloatAction) action; - param = String.valueOf(Math.round(fAction.getNewValue())); - } else if (thing.interfaces.contains("power") && action instanceof BooleanAction) { - actionTypeId = thing.stateByName("power").typeId; - BooleanAction bAction = (BooleanAction) action; - param = bAction.getNewState() == true ? "true" : "false"; - } else if (thing.interfaces.contains("closable") && action instanceof BooleanAction) { - BooleanAction bAction = (BooleanAction) action; - if (bAction.getNewState()) { - Log.d(TAG, "executing open"); - actionTypeId = thing.actionByName("open").typeId; - } else { - Log.d(TAG, "executing close"); - actionTypeId = thing.actionByName("close").typeId; - } - param = ""; - } else if (thing.interfaces.contains("volumecontroller") && thing.stateByName("volume") != null) { - actionTypeId = thing.stateByName("volume").typeId; - FloatAction fAction = (FloatAction) action; - param = String.valueOf(Math.round(fAction.getNewValue())); - } else { - Log.d(TAG, "Unhandled action for: " + thing.name); - consumer.accept(ControlAction.RESPONSE_FAIL); - return; - } - - m_serviceConnection.executeAction(nymeaId, thing.id, actionTypeId, param); - consumer.accept(ControlAction.RESPONSE_OK); - - } - - private HashMap m_intents = new HashMap(); - - private Control thingToControl(UUID nymeaId, UUID thingId) { -// Log.d(TAG, "Creating control for thing: " + thing.name + " id: " + thing.id); - - NymeaHost nymeaHost = m_serviceConnection.getHosts().get(nymeaId); - Thing thing = nymeaHost.things.get(thingId); - - // NOTE: intentId 1 doesn't work for some reason I don't understand yet... - // so let's make sure we never add "1" to it by always added 100 - int intentId = m_intents.size() + 100; - PendingIntent pi; - if (m_intents.containsKey(thing.id)) { - intentId = m_intents.get(thing.id); - } else { - m_intents.put(thing.id, intentId); - } - - Context context = getBaseContext(); - Intent intent = new Intent(context, NymeaAppControlsActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); - intent.putExtra("nymeaId", nymeaId.toString()); - intent.putExtra("thingId", thing.id.toString()); - pi = PendingIntent.getActivity(context, intentId, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); - Log.d(TAG, "Created pendingintent for " + thing.name + " with id " + intentId + " and extra " + thing.id); - - Control.StatefulBuilder builder = new Control.StatefulBuilder(thing.id.toString(), pi) - .setTitle(thing.name) - .setSubtitle(thing.className) - .setStructure(nymeaHost.name); - - if (thing.interfaces.contains("impulsebasedgaragedoor")) { - builder.setDeviceType(DeviceTypes.TYPE_GARAGE); - builder.setControlTemplate(new StatelessTemplate(thing.id.toString())); - } else if (thing.interfaces.contains("statefulgaragedoor")) { - builder.setDeviceType(DeviceTypes.TYPE_GARAGE); - State stateState = thing.stateByName("state"); - ControlButton controlButton = new ControlButton(stateState.value.equals("open"), stateState.displayName); - builder.setControlTemplate(new ToggleTemplate(thing.id.toString(), controlButton)); - -// } else if (thing.interfaces.contains("extendedstatefulgaragedoor")) { -// builder.setDeviceTyoe(DeviceTypes.TYPE_GARAGE); - - } else if (thing.interfaces.contains("light")) { - builder.setDeviceType(DeviceTypes.TYPE_LIGHT); - State powerState = thing.stateByName("power"); - ControlButton controlButton = new ControlButton(powerState.value.equals("true"), powerState.displayName); - - if (thing.interfaces.contains("dimmablelight")) { - State brightnessState = thing.stateByName("brightness"); - RangeTemplate rangeTemplate = new RangeTemplate(thing.id.toString(), 0, 100, Float.parseFloat(brightnessState.value), 1, brightnessState.displayName); - builder.setControlTemplate(new ToggleRangeTemplate(thing.id.toString(), controlButton, rangeTemplate)); - } else { - builder.setControlTemplate(new ToggleTemplate(thing.id.toString(), controlButton)); - } - } else if (thing.interfaces.contains("powersocket")) { - builder.setDeviceType(DeviceTypes.TYPE_OUTLET); - State powerState = thing.stateByName("power"); - ControlButton controlButton = new ControlButton(powerState.value.equals("true"), powerState.displayName); - builder.setControlTemplate(new ToggleTemplate(thing.id.toString(), controlButton)); - } else if (thing.interfaces.contains("mediaplayer")) { - if (thing.stateByName("playerType").value == "video") { - builder.setDeviceType(DeviceTypes.TYPE_TV); - } else { - // FIXME: There doesn't seem to be a speaker DeviceType!?! - builder.setDeviceType(DeviceTypes.TYPE_TV); - } - if (thing.interfaces.contains("volumecontroller")) { - State volumeState = thing.stateByName("volume"); - if (volumeState != null) { - RangeTemplate rangeTemplate = new RangeTemplate(thing.id.toString(), 0, 100, Float.parseFloat(volumeState.value), 1, volumeState.displayName); - builder.setControlTemplate(rangeTemplate); - } - } - } else { - builder.setDeviceType(DeviceTypes.TYPE_GENERIC_ON_OFF); - } - builder.setStatus(Control.STATUS_OK); - -// Log.d(TAG, "Created control for thing: " + thing.name + " id: " + thing.id); - return builder.build(); - } -} diff --git a/androidservice/java/io/guh/nymeaapp/NymeaAppControlsActivity.java b/androidservice/java/io/guh/nymeaapp/NymeaAppControlsActivity.java deleted file mode 100644 index 3b94d25e..00000000 --- a/androidservice/java/io/guh/nymeaapp/NymeaAppControlsActivity.java +++ /dev/null @@ -1,55 +0,0 @@ -package io.guh.nymeaapp; -import android.util.Log; -import android.content.Intent; -import android.content.Context; -import android.os.Bundle; -import android.os.Build; -import android.telephony.TelephonyManager; -import android.provider.Settings.Secure; -import android.os.Vibrator; -import android.os.Process; -import android.nfc.NfcAdapter; -import android.nfc.NdefMessage; -import android.os.Parcelable; - -// An activity spawned by android device controls on demand. - -public class NymeaAppControlsActivity extends org.qtproject.qt5.android.bindings.QtActivity -{ - private static final String TAG = "nymea-app: NymeaAppControlActivity"; - - - @Override public void onPause() { - Log.d(TAG, "Pausing..."); - System.exit(0); - } - - @Override public void onResume() { - super.onResume(); - Log.d(TAG, "Resuming..."); - } - - @Override public void onDestroy() { - Log.d(TAG, "Destroying..."); - } - - public boolean startedByNfc() { - return NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction()); - } - - public String nymeaId() - { - return getIntent().getStringExtra("nymeaId"); - } - - public String thingId() - { - return getIntent().getStringExtra("thingId"); - } - - public void vibrate(int duration) - { - Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); - v.vibrate(duration); - } -} diff --git a/androidservice/java/io/guh/nymeaapp/NymeaAppService.java b/androidservice/java/io/guh/nymeaapp/NymeaAppService.java deleted file mode 100644 index 5bc6acf7..00000000 --- a/androidservice/java/io/guh/nymeaapp/NymeaAppService.java +++ /dev/null @@ -1,50 +0,0 @@ -package io.guh.nymeaapp; - -import android.content.Context; -import android.content.Intent; -import android.util.Log; - -import org.qtproject.qt5.android.bindings.QtService; - -// Background service establishing a connection to nymea and providing data on android specific interfaces -// such as IBinder and BroadcastListener - -// This service loads the service_main Qt entry point and does most of its work in C++/Qt - -public class NymeaAppService extends QtService -{ - public static final String NYMEA_APP_BROADCAST = "io.guh.nymeaapp.NymeaAppService.broadcast"; - - private static final String TAG = "nymea-app: NymeaAppService"; - - @Override - public void onCreate() { - super.onCreate(); - Log.i(TAG, "Creating Service"); - } - - @Override - public void onDestroy() { - super.onDestroy(); - Log.i(TAG, "Destroying Service"); - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - int ret = super.onStartCommand(intent, flags, startId); - - // Do some work - - Log.d(TAG, "*************** Service started"); - - return ret; - } - - public void sendBroadcast(String payload) { - Intent sendToUiIntent = new Intent(); - sendToUiIntent.setAction(NYMEA_APP_BROADCAST); - sendToUiIntent.putExtra("data", payload); -// Log.d(TAG, "Service sending broadcast"); - sendBroadcast(sendToUiIntent); - } -} diff --git a/androidservice/java/io/guh/nymeaapp/NymeaAppServiceConnection.java b/androidservice/java/io/guh/nymeaapp/NymeaAppServiceConnection.java deleted file mode 100644 index fd3c3b1b..00000000 --- a/androidservice/java/io/guh/nymeaapp/NymeaAppServiceConnection.java +++ /dev/null @@ -1,283 +0,0 @@ -package io.guh.nymeaapp; - -import java.util.List; -import java.util.ArrayList; -import java.util.UUID; -import java.util.HashMap; - -import android.util.Log; - -import android.os.IBinder; -import android.os.Parcel; -import android.os.RemoteException; - -import android.content.Intent; -import android.content.IntentFilter; -import android.content.BroadcastReceiver; -import android.content.ServiceConnection; -import android.content.ComponentName; -import android.content.Context; - -import android.service.controls.Control; -import android.service.controls.DeviceTypes; - -import io.reactivex.processors.ReplayProcessor; - -import org.json.*; - -// Helper class to establish a connection to the NymeaAppService and interact -// with that using IBinder and ServiceBroadcastListener - -public class NymeaAppServiceConnection implements ServiceConnection { - private static final String TAG = "nymea-app: NymeaAppServiceConnection"; - private IBinder m_service; - private Context m_context; - - private boolean m_connected = false; - private HashMap m_nymeaHosts = new HashMap(); - - public NymeaAppServiceConnection(Context context) { - super(); - m_context = context; - } - - final public boolean connected() { - return m_connected; - } - public void onConnectedChanged(boolean connected) {}; - - final public boolean isReady(UUID nymeaId) { - return m_nymeaHosts.get(nymeaId).isReady; - } - public void onReadyChanged(UUID nymeaId, boolean ready) {} - - public final HashMap getHosts() { - return m_nymeaHosts; - } - - final public Thing getThing(UUID thingId) { - for (HashMap.Entry entry : m_nymeaHosts.entrySet()) { - Thing thing = entry.getValue().things.get(thingId); - if (thing != null) { - return thing; - } - } - return null; - } - final public UUID hostForThing(UUID thingId) { - for (HashMap.Entry entry : m_nymeaHosts.entrySet()) { - Thing thing = entry.getValue().things.get(thingId); - if (thing != null) { - return entry.getKey(); - } - } - return null; - } - - public void onError() {} - public void onUpdate(UUID nymeaId, UUID thingId) {} - - final public void executeAction(UUID nymeaId, UUID thingId, UUID actionTypeId, String paramValue) { - try { - JSONObject params = new JSONObject(); - params.put("nymeaId", nymeaId.toString()); - params.put("thingId", thingId.toString()); - params.put("actionTypeId", actionTypeId.toString()); - JSONArray actionParams = new JSONArray(); - JSONObject param = new JSONObject(); - param.put("paramTypeId", actionTypeId.toString()); - param.put("value", paramValue); - actionParams.put(param); - params.put("params", actionParams); - Parcel parcel = createRequest("ExecuteAction", params); - Parcel retParcel = Parcel.obtain(); - m_service.transact(1, parcel, retParcel, 0); - } catch (Exception e) { - Log.d(TAG, "Error calling executeAction on NymeaAppService"); - } - } - - @Override public void onServiceConnected(ComponentName className, IBinder service) { - Log.d(TAG, "Connected to NymeaAppService"); - m_service = service; - - registerServiceBroadcastReceiver(); - - try { - Parcel parcel = createRequest("GetInstances"); - Parcel retParcel = Parcel.obtain(); - - m_service.transact(1, parcel, retParcel, 0); - - JSONObject reply = new JSONObject(retParcel.readString()); - Log.d(TAG, "Instaces received: " + reply.toString()); - JSONArray instances = reply.getJSONArray("instances"); - for (int i = 0; i < instances.length(); i++) { - JSONObject instanceMap = instances.getJSONObject(i); - NymeaHost nymeaHost = new NymeaHost(); - nymeaHost.id = UUID.fromString(instanceMap.getString("id")); - nymeaHost.name = instanceMap.getString("name"); - nymeaHost.isReady = instanceMap.getBoolean("isReady"); - m_nymeaHosts.put(nymeaHost.id, nymeaHost); - if (nymeaHost.isReady) { - fetchThings(nymeaHost.id); - } - } - } catch (JSONException e) { - Log.d(TAG, "Error while processing JSON in communication with NymeaAppService: " + e.toString()); - onError(); - return; - } catch (RemoteException e) { - Log.d(TAG, "Error communicating with NymeaAppService: " + e.toString()); - onError(); - return; - } - - m_connected = true; - onConnectedChanged(m_connected); - } - - @Override public void onServiceDisconnected(ComponentName arg0) { - m_service = null; - for (int i = 0; i < m_nymeaHosts.size(); i++) { - m_nymeaHosts.get(i).isReady = false; - } - m_connected = false; - onConnectedChanged(m_connected); - } - - public void registerServiceBroadcastReceiver() { - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(NymeaAppService.NYMEA_APP_BROADCAST); - m_context.registerReceiver(serviceMessageReceiver, intentFilter); - Log.d(TAG, "Registered broadcast receiver"); - } - - private BroadcastReceiver serviceMessageReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (NymeaAppService.NYMEA_APP_BROADCAST.equals(intent.getAction())) { - String payload = intent.getStringExtra("data"); - try { - processBroadcast(payload); - } catch(JSONException e) { - Log.d(TAG, "Error parsing broadcast JSON: " + e.toString()); - } - } - } - }; - - private void processBroadcast(String payload) throws JSONException - { - JSONObject data = new JSONObject(payload); - JSONObject params = data.getJSONObject("params"); -// Log.d(TAG, "Broadcast received from NymeaAppService: " + data.getString("notification")); - Log.d(TAG, params.toString()); - - if (data.getString("notification").equals("ThingStateChanged")) { - UUID nymeaId = UUID.fromString(params.getString("nymeaId")); - UUID thingId = UUID.fromString(params.getString("thingId")); - UUID stateTypeId = UUID.fromString(params.getString("stateTypeId")); - String value = params.getString("value"); -// Log.d(TAG, "Thing state changed: " + thingId + " stateTypeId: " + stateTypeId + " value: " + value); - - Thing thing = getThing(thingId); - if (thing != null) { - thing.stateById(stateTypeId).value = value; - onUpdate(nymeaId, thingId); - } else { - Log.d(TAG, "Got a state change notification for a thing we don't know!"); - } - } - - if (data.getString("notification").equals("ReadyStateChanged")) { - UUID nymeaId = UUID.fromString(params.getString("nymeaId")); - NymeaHost host = m_nymeaHosts.get(nymeaId); - host.isReady = params.getBoolean("isReady"); - if (host.isReady) { - Log.d(TAG, "Host is ready. Fetching things..."); - fetchThings(nymeaId); - } else { - Log.d(TAG, "Host is not ready yet..."); - } - } - } - - private void fetchThings(UUID nymeaId) { - Log.d(TAG, "Fetching things"); - String thingsList; - try { - JSONObject params = new JSONObject(); - params.put("nymeaId", nymeaId.toString()); - Parcel parcel = createRequest("GetThings", params); - Parcel retParcel = Parcel.obtain(); - m_service.transact(1, parcel, retParcel, 0); - thingsList = retParcel.readString(); - } catch (Exception e) { - Log.d(TAG, "Error fetching things from NymeaAppService: " + e.toString()); - onError(); - return; - } - - try { - JSONObject result = new JSONObject(thingsList); - for (int i = 0; i < result.getJSONArray("things").length(); i++) { - JSONObject entry = result.getJSONArray("things").getJSONObject(i); - Thing thing = new Thing(); - thing.id = UUID.fromString(entry.getString("id")); - thing.name = entry.getString("name"); - thing.className = entry.getString("className"); - JSONArray ifaces = entry.getJSONArray("interfaces"); - for (int j = 0; j < ifaces.length(); j++) { - thing.interfaces.add(ifaces.get(j)); - } - JSONArray states = entry.getJSONArray("states"); - for (int j = 0; j < states.length(); j++) { - JSONObject stateMap = states.getJSONObject(j); - State s = new State(); - s.typeId = UUID.fromString(stateMap.getString("stateTypeId")); - s.name = stateMap.getString("name"); - s.displayName = stateMap.getString("displayName"); - s.value = stateMap.getString("value"); - thing.states.add(s); - } - JSONArray actions = entry.getJSONArray("actions"); - for (int j = 0; j < actions.length(); j++) { - JSONObject actionMap = actions.getJSONObject(j); - Action a = new Action(); - a.typeId = UUID.fromString(actionMap.getString("actionTypeId")); - a.name = actionMap.getString("name"); - a.displayName = actionMap.getString("displayName"); - thing.actions.add(a); - } - m_nymeaHosts.get(nymeaId).things.put(thing.id, thing); - } - - } catch (Exception e) { - Log.d(TAG, "Error parsing JSON from NymeaAppService: " + e.toString()); - Log.d(TAG, thingsList); - m_service = null; - onError(); - return; - } - - Log.d(TAG, "Things fetched: " + m_nymeaHosts.get(nymeaId).things.size()); - m_nymeaHosts.get(nymeaId).isReady = true; - onReadyChanged(nymeaId, true); - } - - private Parcel createRequest(String method) throws JSONException { - return createRequest(method, null); - } - private Parcel createRequest(String method, JSONObject params) throws JSONException { - Parcel ret = Parcel.obtain(); - JSONObject payload = new JSONObject(); - payload.put("method", method); - if (params != null) { - payload.put("params", params); - } - Log.d(TAG, "Parcel payload: " + payload.toString()); - ret.writeString(payload.toString()); - return ret; - } -} diff --git a/androidservice/java/io/guh/nymeaapp/NymeaHost.java b/androidservice/java/io/guh/nymeaapp/NymeaHost.java deleted file mode 100644 index a568563c..00000000 --- a/androidservice/java/io/guh/nymeaapp/NymeaHost.java +++ /dev/null @@ -1,13 +0,0 @@ -package io.guh.nymeaapp; - -import java.util.HashMap; -import java.util.ArrayList; -import java.util.UUID; - -public class NymeaHost { - - UUID id; - boolean isReady = false; - String name = ""; - HashMap things = new HashMap(); -} diff --git a/androidservice/java/io/guh/nymeaapp/State.java b/androidservice/java/io/guh/nymeaapp/State.java deleted file mode 100644 index 5b7053ea..00000000 --- a/androidservice/java/io/guh/nymeaapp/State.java +++ /dev/null @@ -1,10 +0,0 @@ -package io.guh.nymeaapp; - -import java.util.UUID; - -public class State { - public UUID typeId; - public String name; - public String displayName; - public String value; -} diff --git a/androidservice/java/io/guh/nymeaapp/Thing.java b/androidservice/java/io/guh/nymeaapp/Thing.java deleted file mode 100644 index e5667831..00000000 --- a/androidservice/java/io/guh/nymeaapp/Thing.java +++ /dev/null @@ -1,56 +0,0 @@ -package io.guh.nymeaapp; - -import android.util.Log; - -import java.util.List; -import java.util.ArrayList; -import java.util.UUID; - - -public class Thing { - static final public String TAG = "nymea-app: Thing"; - public UUID id; - public String name; - public String className; - public List interfaces = new ArrayList(); - - public ArrayList states = new ArrayList(); - public ArrayList actions = new ArrayList(); - - public State stateByName(String name) { - for (int i = 0; i < states.size(); i++) { - if (states.get(i).name.equals(name)) { - return states.get(i); - } - } - return null; - } - - public State stateById(UUID stateTypeId) { - for (int i = 0; i < states.size(); i++) { - if (states.get(i).typeId.equals(stateTypeId)) { - return states.get(i); - } - } - return null; - } - - public Action actionByName(String name) { - for (int i = 0; i < actions.size(); i++) { - Log.d(TAG, "Thing has action: " + actions.get(i).name); - if (actions.get(i).name.equals(name)) { - return actions.get(i); - } - } - return null; - } - - public Action actionById(UUID actionTypeId) { - for (int i = 0; i < actions.size(); i++) { - if (actions.get(i).typeId.equals(actionTypeId)) { - return actions.get(i); - } - } - return null; - } -} diff --git a/androidservice/nymeaappservice/androidbinder.cpp b/androidservice/nymeaappservice/androidbinder.cpp deleted file mode 100644 index 41696887..00000000 --- a/androidservice/nymeaappservice/androidbinder.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include "androidbinder.h" -#include "engine.h" -#include "types/thing.h" - -#include -#include -#include -#include -#include - -AndroidBinder::AndroidBinder(NymeaAppService *service): - m_service(service) -{ -} - -bool AndroidBinder::onTransact(int code, const QAndroidParcel &data, const QAndroidParcel &reply, QAndroidBinder::CallType flags) -{ - qDebug() << "onTransact: code " << code << ", flags " << int(flags); - -// QString payload = data.readData(); - QString payload = data.handle().callObjectMethod("readString").toString(); - - QJsonParseError error; - QJsonDocument jsonDoc = QJsonDocument::fromJson(payload.toUtf8(), &error); - if (error.error != QJsonParseError::NoError) { - qWarning() << "Error parsing JSON from parcel:" << error.errorString(); - qWarning() << payload; - return false; - } - QVariantMap request = jsonDoc.toVariant().toMap(); - - if (request.value("method").toString() == "GetInstances") { - QVariantMap params; - QVariantList instances; - foreach (const QUuid &nymeaId, m_service->engines().keys()) { - Engine *engine = m_service->engines().value(nymeaId); - QVariantMap instance; - instance.insert("id", nymeaId); - instance.insert("isReady", engine->jsonRpcClient()->connected() && !engine->thingManager()->fetchingData()); - instance.insert("name", engine->jsonRpcClient()->currentHost()->name()); - instances.append(instance); - } - params.insert("instances", instances); - sendReply(reply, params); - return true; - } - - if (request.value("method").toString() == "GetThings") { - QUuid nymeaId = request.value("params").toMap().value("nymeaId").toUuid(); - Engine *engine = m_service->engines().value(nymeaId); - if (!engine) { - qWarning() << "Android client requested things for an invalid nymea instance:" << nymeaId; - return false; - } - QVariantList thingsList; - for (int i = 0; i < engine->thingManager()->things()->rowCount(); i++) { - Thing *thing = engine->thingManager()->things()->get(i); - QVariantMap thingMap; - thingMap.insert("id", thing->id()); - thingMap.insert("name", thing->name()); - thingMap.insert("className", thing->thingClass()->displayName()); - thingMap.insert("interfaces", thing->thingClass()->interfaces()); - QVariantList states; - for (int j = 0; j < thing->states()->rowCount(); j++) { - State *state = thing->states()->get(j); - QVariantMap stateMap; - stateMap.insert("stateTypeId", state->stateTypeId()); - stateMap.insert("name", thing->thingClass()->stateTypes()->getStateType(state->stateTypeId())->name()); - stateMap.insert("displayName", thing->thingClass()->stateTypes()->getStateType(state->stateTypeId())->displayName()); - stateMap.insert("value", state->value()); - states.append(stateMap); - } - thingMap.insert("states", states); - QVariantList actions; - for (int j = 0; j < thing->thingClass()->actionTypes()->rowCount(); j++) { - ActionType *actionType = thing->thingClass()->actionTypes()->get(j); - QVariantMap actionMap; - actionMap.insert("actionTypeId", actionType->id()); - actionMap.insert("name", actionType->name()); - actionMap.insert("displayName", actionType->displayName()); - actions.append(actionMap); - } - thingMap.insert("actions", actions); - thingsList.append(thingMap); - } - QVariantMap params; - params.insert("things", thingsList); - sendReply(reply, params); - return true; - } - - if (request.value("method").toString() == "ExecuteAction") { - qDebug() << "ExecuteAction"; - QUuid nymeaId = request.value("params").toMap().value("nymeaId").toUuid(); - Engine *engine = m_service->engines().value(nymeaId); - if (!engine) { - qWarning() << "Android client requested executeAction for an invalid nymea instance:" << nymeaId; - return false; - } - QUuid thingId = request.value("params").toMap().value("thingId").toUuid(); - QUuid actionTypeId = request.value("params").toMap().value("actionTypeId").toUuid(); - QVariantList params = request.value("params").toMap().value("params").toList(); - - qDebug() << "**** executeAction:" << thingId << actionTypeId << params; - engine->thingManager()->executeAction(thingId, actionTypeId, params); - } - - return false; -} - -void AndroidBinder::sendReply(const QAndroidParcel &reply, const QVariantMap ¶ms) -{ - QString payload = QJsonDocument::fromVariant(params).toJson(); - reply.handle().callMethod("writeString", "(Ljava/lang/String;)V", QAndroidJniObject::fromString(payload).object()); -} diff --git a/androidservice/nymeaappservice/androidbinder.h b/androidservice/nymeaappservice/androidbinder.h deleted file mode 100644 index 36a9b795..00000000 --- a/androidservice/nymeaappservice/androidbinder.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef ANDROIDBINDER_H -#define ANDROIDBINDER_H - -#include - -#include "nymeaappservice.h" -#include "engine.h" - -class AndroidBinder : public QAndroidBinder -{ -public: - explicit AndroidBinder(NymeaAppService *service); - - bool onTransact(int code, const QAndroidParcel &data, const QAndroidParcel &reply, QAndroidBinder::CallType flags) override; - -private: - void sendReply(const QAndroidParcel &reply, const QVariantMap ¶ms); - -private: - NymeaAppService *m_service = nullptr; -}; - -#endif // ANDROIDBINDER_H diff --git a/androidservice/nymeaappservice/nymeaappservice.cpp b/androidservice/nymeaappservice/nymeaappservice.cpp deleted file mode 100644 index 76a2d4a8..00000000 --- a/androidservice/nymeaappservice/nymeaappservice.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include "nymeaappservice.h" -#include "androidbinder.h" - -#include -#include -#include -#include - -#include "connection/discovery/nymeadiscovery.h" -#include "connection/nymeahosts.h" - -NymeaAppService::NymeaAppService(int argc, char **argv): - QAndroidService(argc, argv, [=](const QAndroidIntent &) { - return new AndroidBinder{this}; - }) -{ - setApplicationName("nymea-app"); - setOrganizationName("nymea"); - - QSettings settings; - - NymeaDiscovery *discovery = new NymeaDiscovery(this); - - settings.beginGroup("ConfiguredHosts"); - foreach (const QString &childGroup, settings.childGroups()) { - settings.beginGroup(childGroup); - QUuid lastConnected = settings.value("uuid").toUuid(); - QString cachedName = settings.value("cachedName").toString(); - settings.endGroup(); - - if (lastConnected.isNull()) { - continue; - } - NymeaHost *host = discovery->nymeaHosts()->find(lastConnected); - if (!host) { - continue; - } - - Engine *engine = new Engine(this); - engine->jsonRpcClient()->connectToHost(host); - m_engines.insert(host->uuid(), engine); - - - QObject::connect(engine->thingManager(), &ThingManager::thingStateChanged, [=](const QUuid &thingId, const QUuid &stateTypeId, const QVariant &value){ - QVariantMap params; - params.insert("nymeaId", engine->jsonRpcClient()->currentHost()->uuid()); - params.insert("thingId", thingId); - params.insert("stateTypeId", stateTypeId); - params.insert("value", value); - sendNotification("ThingStateChanged", params); - }); - - connect(engine->thingManager(), &ThingManager::fetchingDataChanged, [=]() { - qDebug() << "Fetching data changed"; - QVariantMap params; - params.insert("nymeaId", engine->jsonRpcClient()->currentHost()->uuid()); - params.insert("isReady", !engine->thingManager()->fetchingData()); - qDebug() << "Nymea host is ready" << engine->jsonRpcClient()->currentHost()->uuid(); - sendNotification("ReadyStateChanged", params); - }); - } - settings.endGroup(); - - qDebug() << "NymeaAppService started."; - -} - -QHash NymeaAppService::engines() const -{ - return m_engines; -} - -void NymeaAppService::sendNotification(const QString ¬ification, const QVariantMap ¶ms) -{ - QVariantMap data; - data.insert("notification", notification); - data.insert("params", params); - QString payload = QJsonDocument::fromVariant(data).toJson(); - QtAndroid::androidService().callMethod("sendBroadcast", - "(Ljava/lang/String;)V", - QAndroidJniObject::fromString(payload).object()); - -} diff --git a/androidservice/nymeaappservice/nymeaappservice.h b/androidservice/nymeaappservice/nymeaappservice.h deleted file mode 100644 index 5e823efa..00000000 --- a/androidservice/nymeaappservice/nymeaappservice.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef NYMEAAPPSERVICE_H -#define NYMEAAPPSERVICE_H - -#include -#include -#include - -#include "engine.h" - -class NymeaAppService : public QAndroidService -{ - Q_OBJECT -public: - explicit NymeaAppService(int argc, char** argv); - - QHash engines() const; - -private: - void sendNotification(const QString ¬ification, const QVariantMap ¶ms); - - -private: - QHash m_engines; - -}; - -#endif // NYMEAAPPSERVICE_H diff --git a/androidservice/service_main.cpp b/androidservice/service_main.cpp deleted file mode 100644 index 46efab22..00000000 --- a/androidservice/service_main.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include - -#include "nymeaappservice/nymeaappservice.h" -#include "controlviews/devicecontrolapplication.h" - -#include -#include - -int main(int argc, char *argv[]) -{ - qWarning() << "Service starting from a separate .so file"; - - QLoggingCategory::setFilterRules("qt.remoteobjects.debug=true\n"); - - QStringList args; - for (int i = 0; i < argc; i++) { - args.append(QByteArray(argv[i])); - qDebug() << "nymea-app: Added command line arg" << args.last(); - } - QCommandLineParser parser; - QCommandLineOption controlActivityOption("controlActivity"); - parser.addOption(controlActivityOption); - parser.parse(args); - - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - - QCoreApplication *app; - if (parser.isSet(controlActivityOption)) { - qDebug() << "nymea-app: Starting Device Control Activity"; - app = new DeviceControlApplication(argc, argv); - } else { - qDebug() << "nymea-app: Starting NymeaAppService background service"; - app = new NymeaAppService(argc, argv); - } - return app->exec(); -} diff --git a/config.h.in.qmake b/config.h.in.qmake new file mode 100644 index 00000000..ed2ba667 --- /dev/null +++ b/config.h.in.qmake @@ -0,0 +1,71 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2020, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea. +* This project including source code and documentation is protected by +* copyright law, and remains the property of nymea GmbH. All rights, including +* reproduction, publication, editing and translation, are reserved. The use of +* this project is subject to the terms of a license agreement to be concluded +* with nymea GmbH in accordance with the terms of use of nymea GmbH, available +* under https://nymea.io/license +* +* GNU General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the +* terms of the GNU General Public License as published by the Free Software +* Foundation, GNU version 3. This project is distributed in the hope that it +* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +* Public License for more details. +* +* You should have received a copy of the GNU General Public License along with +* this project. If not, see . +* +* For any further details and any questions please contact us under +* contact@nymea.io or see our FAQ/Licensing Information on +* https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef VERSION_H +#define VERSION_H + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2020, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea. +* This project including source code and documentation is protected by +* copyright law, and remains the property of nymea GmbH. All rights, including +* reproduction, publication, editing and translation, are reserved. The use of +* this project is subject to the terms of a license agreement to be concluded +* with nymea GmbH in accordance with the terms of use of nymea GmbH, available +* under https://nymea.io/license +* +* GNU General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the +* terms of the GNU General Public License as published by the Free Software +* Foundation, GNU version 3. This project is distributed in the hope that it +* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +* Public License for more details. +* +* You should have received a copy of the GNU General Public License along with +* this project. If not, see . +* +* For any further details and any questions please contact us under +* contact@nymea.io or see our FAQ/Licensing Information on +* https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef VERSION_H +#define VERSION_H + +#define APP_VERSION '"$$APP_VERSION"' +#define APPLICATION_NAME '"$$APPLICATION_NAME"' +#define ORGANISATION_NAME '"$$ORGANISATION_NAME"' + +#endif diff --git a/debian b/debian index 3f3d1dfa..cf793782 120000 --- a/debian +++ b/debian @@ -1 +1 @@ -packaging/ubuntu/debian/ \ No newline at end of file +packaging/ubuntu/debian-qt6/ \ No newline at end of file diff --git a/experiences/CMakeLists.txt b/experiences/CMakeLists.txt new file mode 100644 index 00000000..cb6c01f9 --- /dev/null +++ b/experiences/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(airconditioning) diff --git a/experiences/airconditioning/CMakeLists.txt b/experiences/airconditioning/CMakeLists.txt new file mode 100644 index 00000000..58d56a13 --- /dev/null +++ b/experiences/airconditioning/CMakeLists.txt @@ -0,0 +1,31 @@ +file(GLOB AIRCONDITIONING_SOURCES CONFIGURE_DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp +) +file(GLOB AIRCONDITIONING_HEADERS CONFIGURE_DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/*.h +) + +add_library(nymea-app-airconditioning STATIC + ${AIRCONDITIONING_SOURCES} + ${AIRCONDITIONING_HEADERS} +) +set_target_properties(nymea-app-airconditioning PROPERTIES OUTPUT_NAME "nymea-app-airconditioning") + +target_include_directories(nymea-app-airconditioning + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/libnymea-app + ${CMAKE_BINARY_DIR} +) + +target_link_libraries(nymea-app-airconditioning + PUBLIC + nymea-app-core + Qt6::Core + Qt6::Network + Qt6::WebSockets + Qt6::Bluetooth + Qt6::Charts + Qt6::Quick + Qt6::Qml +) diff --git a/experiences/airconditioning/airconditioning.pro b/experiences/airconditioning/airconditioning.pro index 9ca7c8ab..67657a29 100644 --- a/experiences/airconditioning/airconditioning.pro +++ b/experiences/airconditioning/airconditioning.pro @@ -10,8 +10,8 @@ include(../../shared.pri) LIBS += -L$${top_builddir}/libnymea-app/ -lnymea-app android: { -LIBS += -L$${top_builddir}/libnymea-app/$${ANDROID_TARGET_ARCH} -PRE_TARGETDEPS += $$top_builddir/libnymea-app/$${ANDROID_TARGET_ARCH}/libnymea-app.a + LIBS += -L$${top_builddir}/libnymea-app/$${ANDROID_TARGET_ARCH} + PRE_TARGETDEPS += $$top_builddir/libnymea-app/$${ANDROID_TARGET_ARCH}/libnymea-app_$${ANDROID_TARGET_ARCH}.a } INCLUDEPATH += $${top_srcdir}/libnymea-app/ diff --git a/experiences/airconditioning/airconditioningmanager.cpp b/experiences/airconditioning/airconditioningmanager.cpp index 32d0dde8..23fc2822 100644 --- a/experiences/airconditioning/airconditioningmanager.cpp +++ b/experiences/airconditioning/airconditioningmanager.cpp @@ -25,8 +25,6 @@ #include "airconditioningmanager.h" #include "zoneinfo.h" -#include "engine.h" - #include #include diff --git a/experiences/airconditioning/airconditioningmanager.h b/experiences/airconditioning/airconditioningmanager.h index 071090d9..3d3a051a 100644 --- a/experiences/airconditioning/airconditioningmanager.h +++ b/experiences/airconditioning/airconditioningmanager.h @@ -28,8 +28,7 @@ #include #include "zoneinfo.h" - -class Engine; +#include "engine.h" class AirConditioningManager : public QObject { diff --git a/libnymea-app/CMakeLists.txt b/libnymea-app/CMakeLists.txt new file mode 100644 index 00000000..0dd7288e --- /dev/null +++ b/libnymea-app/CMakeLists.txt @@ -0,0 +1,116 @@ +set(LIBNYMEA_APP_SOURCES) +file(GLOB_RECURSE LIBNYMEA_APP_SOURCES CONFIGURE_DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp +) +file(GLOB_RECURSE LIBNYMEA_APP_HEADERS CONFIGURE_DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/*.h +) + +set(NYMEA_REMOTEPROXYCLIENT_MODULE + ${CMAKE_SOURCE_DIR}/nymea-remoteproxy/cmake/nymea-remoteproxyclient-sources.cmake +) + +set(REMOTE_PROXYCLIENT_SOURCES) +set(REMOTE_PROXYCLIENT_HEADERS) +set(REMOTE_PROXYCLIENT_INCLUDE_DIRS) + +if(EXISTS ${NYMEA_REMOTEPROXYCLIENT_MODULE}) + include(${NYMEA_REMOTEPROXYCLIENT_MODULE}) + + if(COMMAND nymea_remoteproxyclient_sources) + nymea_remoteproxyclient_sources( + REMOTE_PROXYCLIENT_SOURCES + REMOTE_PROXYCLIENT_HEADERS + REMOTE_PROXYCLIENT_INCLUDE_DIRS + ) + endif() + + if(DEFINED NYMEA_REMOTEPROXYCLIENT_SOURCES) + list(APPEND REMOTE_PROXYCLIENT_SOURCES ${NYMEA_REMOTEPROXYCLIENT_SOURCES}) + endif() + if(DEFINED NYMEA_REMOTEPROXYCLIENT_HEADERS) + list(APPEND REMOTE_PROXYCLIENT_HEADERS ${NYMEA_REMOTEPROXYCLIENT_HEADERS}) + endif() + if(DEFINED NYMEA_REMOTEPROXYCLIENT_INCLUDE_DIRS) + list(APPEND REMOTE_PROXYCLIENT_INCLUDE_DIRS ${NYMEA_REMOTEPROXYCLIENT_INCLUDE_DIRS}) + endif() + + if(NOT REMOTE_PROXYCLIENT_SOURCES AND NOT REMOTE_PROXYCLIENT_HEADERS) + message(FATAL_ERROR + "nymea-remoteproxyclient module did not populate its source lists. " + "Please ensure nymea-remoteproxy is checked out at the required revision." + ) + endif() +else() + message(FATAL_ERROR + "nymea-remoteproxyclient CMake module not found. Did you initialize the nymea-remoteproxy submodule?" + ) +endif() + +if(NOT REMOTE_PROXYCLIENT_INCLUDE_DIRS) + set(_nymea_remoteproxyclient_root + ${CMAKE_SOURCE_DIR}/nymea-remoteproxy/libnymea-remoteproxyclient + ) + if(EXISTS ${_nymea_remoteproxyclient_root}) + list(APPEND REMOTE_PROXYCLIENT_INCLUDE_DIRS ${_nymea_remoteproxyclient_root}) + endif() + unset(_nymea_remoteproxyclient_root) +endif() + +if(NOT REMOTE_PROXYCLIENT_INCLUDE_DIRS) + message(FATAL_ERROR + "nymea-remoteproxyclient include directories were not provided by the module. " + "Please ensure the nymea-remoteproxy submodule is checked out at the required revision." + ) +endif() + +set(NYMEA_APP_CORE_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_BINARY_DIR} +) + +list(APPEND NYMEA_APP_CORE_INCLUDE_DIRS ${REMOTE_PROXYCLIENT_INCLUDE_DIRS}) + +if(EXISTS ${CMAKE_SOURCE_DIR}/QtZeroConf) + list(APPEND NYMEA_APP_CORE_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/QtZeroConf) +endif() + +add_library(nymea-app-core STATIC + ${LIBNYMEA_APP_SOURCES} + ${LIBNYMEA_APP_HEADERS} + ${REMOTE_PROXYCLIENT_SOURCES} + ${REMOTE_PROXYCLIENT_HEADERS} +) +set_target_properties(nymea-app-core PROPERTIES OUTPUT_NAME "nymea-app") + +list(REMOVE_DUPLICATES NYMEA_APP_CORE_INCLUDE_DIRS) +target_include_directories(nymea-app-core PUBLIC ${NYMEA_APP_CORE_INCLUDE_DIRS}) + +target_link_libraries(nymea-app-core + PUBLIC + Qt6::Core + Qt6::Network + Qt6::WebSockets + Qt6::Bluetooth + Qt6::Charts + Qt6::Quick + Qt6::Qml +) + +if(TARGET OpenSSL::SSL AND TARGET OpenSSL::Crypto) + target_link_libraries(nymea-app-core PUBLIC OpenSSL::SSL OpenSSL::Crypto) +else() + message(WARNING "OpenSSL development libraries not found; continuing without explicit OpenSSL linkage.") +endif() + +if(NYMEA_ENABLE_ZEROCONF) + target_compile_definitions(nymea-app-core PUBLIC WITH_ZEROCONF QZEROCONF_STATIC) + find_library(QTZEROCONF_LIBRARY NAMES QtZeroConf HINTS ${CMAKE_SOURCE_DIR}/QtZeroConf) + if(NOT QTZEROCONF_LIBRARY AND TARGET Qt6::QtZeroConf) + target_link_libraries(nymea-app-core PUBLIC Qt6::QtZeroConf) + elseif(QTZEROCONF_LIBRARY) + target_link_libraries(nymea-app-core PUBLIC ${QTZEROCONF_LIBRARY}) + else() + message(FATAL_ERROR "ZeroConf support requested but QtZeroConf library was not found") + endif() +endif() diff --git a/libnymea-app/configuration/mqttpolicies.h b/libnymea-app/configuration/mqttpolicies.h index 4639d025..b26ec916 100644 --- a/libnymea-app/configuration/mqttpolicies.h +++ b/libnymea-app/configuration/mqttpolicies.h @@ -52,15 +52,17 @@ public: void addPolicy(MqttPolicy *policy); void removePolicy(MqttPolicy *policy); - Q_INVOKABLE MqttPolicy* getPolicy(const QString &clientId) const; - Q_INVOKABLE MqttPolicy* get(int index) const; + Q_INVOKABLE MqttPolicy *getPolicy(const QString &clientId) const; + Q_INVOKABLE MqttPolicy *get(int index) const; void clear(); + signals: void countChanged(); private: - QList m_list; + QList m_list; + }; #endif // MQTTPOLICIES_H diff --git a/libnymea-app/configuration/nymeaconfiguration.h b/libnymea-app/configuration/nymeaconfiguration.h index 7ae0d83f..d1201b04 100644 --- a/libnymea-app/configuration/nymeaconfiguration.h +++ b/libnymea-app/configuration/nymeaconfiguration.h @@ -133,7 +133,7 @@ signals: void serverNameChanged(); private: - JsonRpcClient* m_client = nullptr; + JsonRpcClient *m_client = nullptr; bool m_fetchingData = false; bool m_debugServerEnabled = false; diff --git a/libnymea-app/configuration/serverconfiguration.h b/libnymea-app/configuration/serverconfiguration.h index c5105789..0cef2662 100644 --- a/libnymea-app/configuration/serverconfiguration.h +++ b/libnymea-app/configuration/serverconfiguration.h @@ -56,7 +56,7 @@ public: bool sslEnabled() const; void setSslEnabled(bool sslEnabled); - Q_INVOKABLE virtual ServerConfiguration* clone() const; + Q_INVOKABLE virtual ServerConfiguration *clone() const; signals: void addressChanged(); diff --git a/libnymea-app/configuration/serverconfigurations.h b/libnymea-app/configuration/serverconfigurations.h index 90d4ff26..0477f13c 100644 --- a/libnymea-app/configuration/serverconfigurations.h +++ b/libnymea-app/configuration/serverconfigurations.h @@ -57,8 +57,8 @@ public: void clear(); - Q_INVOKABLE ServerConfiguration* get(int index) const; - Q_INVOKABLE ServerConfiguration* getConfiguration(const QString &id) const; + Q_INVOKABLE ServerConfiguration *get(int index) const; + Q_INVOKABLE ServerConfiguration *getConfiguration(const QString &id) const; signals: void countChanged(); diff --git a/libnymea-app/connection/discovery/bluetoothservicediscovery.cpp b/libnymea-app/connection/discovery/bluetoothservicediscovery.cpp index da51c15a..de64c392 100644 --- a/libnymea-app/connection/discovery/bluetoothservicediscovery.cpp +++ b/libnymea-app/connection/discovery/bluetoothservicediscovery.cpp @@ -24,9 +24,6 @@ #include "bluetoothservicediscovery.h" -#include "../nymeahosts.h" -#include "../nymeahost.h" - #include #include "logging.h" @@ -127,17 +124,6 @@ void BluetoothServiceDiscovery::onServiceDiscovered(const QBluetoothServiceInfo if (serviceInfo.serviceClassUuids().first() == QBluetoothUuid(QUuid("997936b5-d2cd-4c57-b41b-c6048320cd2b"))) { qCDebug(dcBluetoothDiscovery()) << "BluetoothServiceDiscovery: Found nymea rfcom service!"; - -// NymeaHost* host = m_nymeaHosts->find(serviceInfo.device().address()); -// if (!host) { -// host = new DiscoveryDevice(DiscoveryDevice::DeviceTypeBluetooth, this); -// qDebug() << "BluetoothServiceDiscovery: Adding new bluetooth host to model"; -// host->setName(QString("%1 (%2)").arg(serviceInfo.serviceName()).arg(serviceInfo.device().name())); -//// device->setBluetoothAddress(serviceInfo.device().address()); -// PortConfig pc; - -// m_nymeaHosts->addHost(device); -// } } } @@ -157,7 +143,6 @@ void BluetoothServiceDiscovery::onServiceDiscoveryFinished() return; } -// qDebug() << "BluetoothServiceDiscovery: Restart service discovery"; discover(); } } diff --git a/libnymea-app/connection/discovery/nymeadiscovery.h b/libnymea-app/connection/discovery/nymeadiscovery.h index f0e13c29..b062682c 100644 --- a/libnymea-app/connection/discovery/nymeadiscovery.h +++ b/libnymea-app/connection/discovery/nymeadiscovery.h @@ -36,7 +36,6 @@ class UpnpDiscovery; class ZeroconfDiscovery; class BluetoothServiceDiscovery; - class NymeaDiscovery : public QObject { Q_OBJECT diff --git a/libnymea-app/connection/discovery/upnpdiscovery.cpp b/libnymea-app/connection/discovery/upnpdiscovery.cpp index 6a682da7..42310675 100644 --- a/libnymea-app/connection/discovery/upnpdiscovery.cpp +++ b/libnymea-app/connection/discovery/upnpdiscovery.cpp @@ -116,8 +116,13 @@ void UpnpDiscovery::updateInterfaces() } qCInfo(dcUPnP()) << "Discovering on" << netAddressEntry.ip() << port; m_sockets.insert(netAddressEntry.ip(), socket); - connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError))); + connect(socket, &QUdpSocket::readyRead, this, &UpnpDiscovery::readData); +#if QT_VERSION >= QT_VERSION_CHECK(5 , 15, 0) + connect(socket, &QUdpSocket::errorOccurred, this, &UpnpDiscovery::error); +#else + connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError))); +#endif } } diff --git a/libnymea-app/connection/discovery/zeroconfdiscovery.cpp b/libnymea-app/connection/discovery/zeroconfdiscovery.cpp index 7633ef75..e0f24bd2 100644 --- a/libnymea-app/connection/discovery/zeroconfdiscovery.cpp +++ b/libnymea-app/connection/discovery/zeroconfdiscovery.cpp @@ -45,23 +45,23 @@ ZeroconfDiscovery::ZeroconfDiscovery(NymeaHosts *nymeaHosts, QObject *parent) : connect(m_zeroconfJsonRPC, &QZeroConf::serviceUpdated, this, &ZeroconfDiscovery::serviceEntryAdded); connect(m_zeroconfJsonRPC, &QZeroConf::serviceRemoved, this, &ZeroconfDiscovery::serviceEntryRemoved); - if (m_zeroconfJsonRPC->isValid()) { + // if (m_zeroconfJsonRPC->isValid()) { m_zeroconfJsonRPC->startBrowser("_jsonrpc._tcp", QAbstractSocket::IPv4Protocol); qCInfo(dcZeroConf()) << "Created service browser for _jsonrpc._tcp:" << m_zeroconfJsonRPC->browserExists(); - } else { - qCWarning(dcZeroConf()) << "Failed to initialize service broeser for _jsonprc._tcp"; - } + // } else { + // qCWarning(dcZeroConf()) << "Failed to initialize service broeser for _jsonprc._tcp"; + // } m_zeroconfWebSocket = new QZeroConf(this); connect(m_zeroconfWebSocket, &QZeroConf::serviceAdded, this, &ZeroconfDiscovery::serviceEntryAdded); connect(m_zeroconfWebSocket, &QZeroConf::serviceUpdated, this, &ZeroconfDiscovery::serviceEntryAdded); connect(m_zeroconfWebSocket, &QZeroConf::serviceRemoved, this, &ZeroconfDiscovery::serviceEntryRemoved); - if (m_zeroconfWebSocket->isValid()) { + // if (m_zeroconfWebSocket->isValid()) { m_zeroconfWebSocket->startBrowser("_ws._tcp", QAbstractSocket::IPv4Protocol); qCInfo(dcZeroConf()) << "Created service browser for _ws._tcp:" << m_zeroconfWebSocket->browserExists(); - } else { - qCWarning(dcZeroConf()) << "Failed to initialize service browserr for _ws._tcp"; - } + // } else { + // qCWarning(dcZeroConf()) << "Failed to initialize service browserr for _ws._tcp"; + // } #else qCInfo(dcZeroConf()) << "Zeroconf support not compiled in. Zeroconf will not be available."; diff --git a/libnymea-app/connection/networkreachabilitymonitor.cpp b/libnymea-app/connection/networkreachabilitymonitor.cpp index 60a8bc19..da9e9c0a 100644 --- a/libnymea-app/connection/networkreachabilitymonitor.cpp +++ b/libnymea-app/connection/networkreachabilitymonitor.cpp @@ -38,6 +38,25 @@ NetworkReachabilityMonitor::NetworkReachabilityMonitor(QObject *parent) setupIOS(); #endif +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + + m_networkInformation = QNetworkInformation::instance(); + + qCDebug(dcNymeaConnection()) << "Network infromation supported features:" << m_networkInformation->supportedFeatures(); + qCDebug(dcNymeaConnection()) << "Network reachability:" << m_networkInformation->reachability(); + qCDebug(dcNymeaConnection()) << "Network trasport medium changed:" << m_networkInformation->transportMedium(); + + QObject::connect(m_networkInformation, &QNetworkInformation::reachabilityChanged, this, [this](QNetworkInformation::Reachability reachability){ + qCDebug(dcNymeaConnection()) << "Network reachability changed:" << reachability; + updateActiveBearers(); + }); + + QObject::connect(m_networkInformation, &QNetworkInformation::transportMediumChanged, this, [this](QNetworkInformation::TransportMedium type){ + qCDebug(dcNymeaConnection()) << "Network trasport medium changed:" << type; + updateActiveBearers(); + }); + +#else m_networkConfigManager = new QNetworkConfigurationManager(this); QObject::connect(m_networkConfigManager, &QNetworkConfigurationManager::configurationAdded, this, [this](const QNetworkConfiguration &config){ @@ -50,6 +69,7 @@ NetworkReachabilityMonitor::NetworkReachabilityMonitor(QObject *parent) qCDebug(dcNymeaConnection()) << "Network configuration removed:" << config.name() << config.bearerTypeName() << config.purpose(); updateActiveBearers(); }); +#endif QGuiApplication *app = static_cast(QGuiApplication::instance()); QObject::connect(app, &QGuiApplication::applicationStateChanged, this, [this](Qt::ApplicationState state) { @@ -58,7 +78,6 @@ NetworkReachabilityMonitor::NetworkReachabilityMonitor(QObject *parent) }); updateActiveBearers(); - } NetworkReachabilityMonitor::~NetworkReachabilityMonitor() @@ -80,6 +99,16 @@ void NetworkReachabilityMonitor::updateActiveBearers() #endif NymeaConnection::BearerTypes availableBearerTypes; + +// Note: some features are availabe since Qt 6.3.0, but the minimal Qt6 version is 6.6.0, +// so we don't want so have an unhanlded gap and let the compiler warn about incompatibility +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + if (m_networkInformation->reachability() == QNetworkInformation::Reachability::Disconnected) { + qCDebug(dcNymeaConnection()) << "No reachable network transport medium available."; + } else { + availableBearerTypes.setFlag(qBearerTypeToNymeaBearerType(m_networkInformation->transportMedium())); + } +#else QList configs = m_networkConfigManager->allConfigurations(QNetworkConfiguration::Active); qCDebug(dcNymeaConnection()) << "Network configuations:" << configs.count(); foreach (const QNetworkConfiguration &config, configs) { @@ -97,6 +126,7 @@ void NetworkReachabilityMonitor::updateActiveBearers() qCDebug(dcNymeaConnection()) << "Updating network manager"; m_networkConfigManager->updateConfigurations(); } +#endif if (m_availableBearerTypes != availableBearerTypes) { qCInfo(dcNymeaConnection()) << "Available Bearer Types changed to:" << availableBearerTypes; @@ -109,6 +139,27 @@ void NetworkReachabilityMonitor::updateActiveBearers() emit availableBearerTypesUpdated(); } +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +NymeaConnection::BearerType NetworkReachabilityMonitor::qBearerTypeToNymeaBearerType(QNetworkInformation::TransportMedium type) +{ + switch (type) { + case QNetworkInformation::TransportMedium::Unknown: + // Unable to determine the connection type. Assume it's something we can establish any connection type on + return NymeaConnection::BearerTypeAll; + case QNetworkInformation::TransportMedium::Ethernet: + return NymeaConnection::BearerTypeEthernet; + case QNetworkInformation::TransportMedium::Cellular: + return NymeaConnection::BearerTypeMobileData; + case QNetworkInformation::TransportMedium::WiFi: + return NymeaConnection::BearerTypeWiFi; + case QNetworkInformation::TransportMedium::Bluetooth: + // Note: Do not confuse this with the Bluetooth transport... For Qt, this means IP over BT, not RFCOMM as we do it. + return NymeaConnection::BearerTypeBluetooth; + } + + return NymeaConnection::BearerTypeAll; +} +#else NymeaConnection::BearerType NetworkReachabilityMonitor::qBearerTypeToNymeaBearerType(QNetworkConfiguration::BearerType type) { switch (type) { @@ -130,9 +181,11 @@ NymeaConnection::BearerType NetworkReachabilityMonitor::qBearerTypeToNymeaBearer case QNetworkConfiguration::Bearer4G: return NymeaConnection::BearerTypeMobileData; case QNetworkConfiguration::BearerBluetooth: - // Note: Do not confuse this with the Bluetooth transport... For Qt, this means IP over BT, not RFCOMM as we do it. + // Note: Do not confuse this with the Bluetooth transport... For Qt, this means IP over BT, not RFCOMM as we do it. return NymeaConnection::BearerTypeNone; } - return NymeaConnection::BearerTypeAll; + return NymeaConnection::BearerTypeAll; } + +#endif diff --git a/libnymea-app/connection/networkreachabilitymonitor.h b/libnymea-app/connection/networkreachabilitymonitor.h index fd227655..e5c0b802 100644 --- a/libnymea-app/connection/networkreachabilitymonitor.h +++ b/libnymea-app/connection/networkreachabilitymonitor.h @@ -26,14 +26,19 @@ #define NETWORKREACHABILITYMONITOR_H #include -#include -#include "nymeaconnection.h" +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +#include +#else +#include +#endif #ifdef Q_OS_IOS #import #endif +#include "nymeaconnection.h" + class NetworkReachabilityMonitor : public QObject { Q_OBJECT @@ -52,10 +57,16 @@ private slots: void updateActiveBearers(); private: - QNetworkConfigurationManager *m_networkConfigManager = nullptr; NymeaConnection::BearerTypes m_availableBearerTypes = NymeaConnection::BearerTypeNone; +#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) + QNetworkInformation *m_networkInformation = nullptr; + static NymeaConnection::BearerType qBearerTypeToNymeaBearerType(QNetworkInformation::TransportMedium type); +#else + QNetworkConfigurationManager *m_networkConfigManager = nullptr; static NymeaConnection::BearerType qBearerTypeToNymeaBearerType(QNetworkConfiguration::BearerType type); +#endif + #ifdef Q_OS_IOS void setupIOS(); diff --git a/libnymea-app/connection/nymeaconnection.cpp b/libnymea-app/connection/nymeaconnection.cpp index 84f3e53c..969ed0f5 100644 --- a/libnymea-app/connection/nymeaconnection.cpp +++ b/libnymea-app/connection/nymeaconnection.cpp @@ -45,18 +45,21 @@ NYMEA_LOGGING_CATEGORY(dcNymeaConnection, "NymeaConnection") NymeaConnection::NymeaConnection(QObject *parent) : QObject(parent) { -// m_networkConfigManager = new QNetworkConfigurationManager(this); + m_networkReachabilityMonitor = new NetworkReachabilityMonitor(this); + connect(m_networkReachabilityMonitor, &NetworkReachabilityMonitor::availableBearerTypesChanged, this, &NymeaConnection::availableBearerTypesChanged); + connect(m_networkReachabilityMonitor, &NetworkReachabilityMonitor::availableBearerTypesUpdated, this, &NymeaConnection::onAvailableBearerTypesUpdated); -// QObject::connect(m_networkConfigManager, &QNetworkConfigurationManager::configurationAdded, this, [this](const QNetworkConfiguration &config){ -// Q_UNUSED(config) -// qCDebug(dcNymeaConnection()) << "Network configuration added:" << config.name() << config.bearerTypeName() << config.purpose(); -// updateActiveBearers(); -// }); -// QObject::connect(m_networkConfigManager, &QNetworkConfigurationManager::configurationRemoved, this, [this](const QNetworkConfiguration &config){ -// Q_UNUSED(config) -// qCDebug(dcNymeaConnection()) << "Network configuration removed:" << config.name() << config.bearerTypeName() << config.purpose(); -// updateActiveBearers(); -// }); +#ifdef Q_OS_IOS + connect(m_networkReachabilityMonitor, &NetworkReachabilityMonitor::availableBearerTypesChanged, this, [this](){ + if (m_currentTransport) { + qCInfo(dcNymeaConnection()) << "Available bearer types changed:" << m_networkReachabilityMonitor->availableBearerTypes() << "currently used:" << m_usedBearerType; + if (!m_networkReachabilityMonitor->availableBearerTypes().testFlag(m_usedBearerType)) { + qCInfo(dcNymeaConnection()) << "Used bearer type" << m_usedBearerType << "isn't available any more. Reconnecting."; + m_currentTransport->disconnect(); + } + } + }); +#endif QGuiApplication *app = static_cast(QGuiApplication::instance()); QObject::connect(app, &QGuiApplication::applicationStateChanged, this, [app, this](Qt::ApplicationState state) { @@ -313,18 +316,18 @@ void NymeaConnection::onConnected() newTransport->deleteLater(); -// Connection *existingConnection = m_transportCandidates.value(m_currentTransport); -// Connection *alternativeConnection = m_transportCandidates.value(newTransport); -// if (alternativeConnection->priority() > existingConnection->priority()) { -// qDebug() << "New connection has higher priority! Roaming from" << existingConnection->url() << existingConnection->priority() << "to" << alternativeConnection->url() << alternativeConnection->priority(); -// m_transportCandidates.remove(m_currentTransport); -// m_currentTransport->deleteLater(); -// m_currentTransport = newTransport; -// } else { -// qDebug() << "Connection" << alternativeConnection->url() << alternativeConnection->priority() << "has lower priority than existing" << existingConnection->url() << existingConnection->priority(); -// m_transportCandidates.remove(newTransport); -// newTransport->deleteLater(); -// } + // Connection *existingConnection = m_transportCandidates.value(m_currentTransport); + // Connection *alternativeConnection = m_transportCandidates.value(newTransport); + // if (alternativeConnection->priority() > existingConnection->priority()) { + // qDebug() << "New connection has higher priority! Roaming from" << existingConnection->url() << existingConnection->priority() << "to" << alternativeConnection->url() << alternativeConnection->priority(); + // m_transportCandidates.remove(m_currentTransport); + // m_currentTransport->deleteLater(); + // m_currentTransport = newTransport; + // } else { + // qDebug() << "Connection" << alternativeConnection->url() << alternativeConnection->priority() << "has lower priority than existing" << existingConnection->url() << existingConnection->priority(); + // m_transportCandidates.remove(newTransport); + // newTransport->deleteLater(); + // } return; } } @@ -386,7 +389,7 @@ void NymeaConnection::onDataAvailable(const QByteArray &data) { NymeaTransportInterface *t = static_cast(sender()); if (t == m_currentTransport) { -// qCDebug(dcNymeaConnection()) << "Data available"; + // qCDebug(dcNymeaConnection()) << "Data available"; emit dataAvailable(data); } else { qCDebug(dcNymeaConnection()) << "Received data from a transport that is not the current one:" << t->url(); @@ -395,39 +398,6 @@ void NymeaConnection::onDataAvailable(const QByteArray &data) void NymeaConnection::onAvailableBearerTypesUpdated() { - NymeaConnection::BearerTypes availableBearerTypes; -// QList configs = m_networkConfigManager->allConfigurations(QNetworkConfiguration::Active); -// qCDebug(dcNymeaConnection()) << "Network configuations:" << configs.count(); -// foreach (const QNetworkConfiguration &config, configs) { -// qCDebug(dcNymeaConnection()) << "Active network config:" << config.name() << config.bearerTypeFamily() << config.bearerTypeName(); - -// // NOTE: iOS doesn't correctly report bearer types. It'll be Unknown all the time. Let's hardcode it to WiFi for that... -//#if defined(Q_OS_IOS) - availableBearerTypes.setFlag(NymeaConnection::BearerTypeWiFi); -//#else -// availableBearerTypes.setFlag(qBearerTypeToNymeaBearerType(config.bearerType())); -//#endif -// } -// if (availableBearerTypes == NymeaConnection::BearerTypeNone) { -// // This is just debug info... On some platform bearer management seems a bit broken, so let's get some infos right away... -// qCDebug(dcNymeaConnection()) << "No active bearer available. Inactive bearers are:"; -// QList configs = m_networkConfigManager->allConfigurations(); -// foreach (const QNetworkConfiguration &config, configs) { -// qCDebug(dcNymeaConnection()) << "Inactive network config:" << config.name() << config.bearerTypeFamily() << config.bearerTypeName(); -// } - -// qCDebug(dcNymeaConnection()) << "Updating network manager"; -// m_networkConfigManager->updateConfigurations(); -// } - - if (m_availableBearerTypes != availableBearerTypes) { - qCInfo(dcNymeaConnection()) << "Available Bearer Types changed to:" << availableBearerTypes; - m_availableBearerTypes = availableBearerTypes; - emit availableBearerTypesChanged(); - } else { - qCDebug(dcNymeaConnection()) << "Available Bearer Types:" << availableBearerTypes; - } - if (!m_currentHost) { // No host set... Nothing to do... qCInfo(dcNymeaConnection()) << "No current host... Nothing to do..."; @@ -446,7 +416,7 @@ void NymeaConnection::onAvailableBearerTypesUpdated() if (!m_currentTransport) { // There's a host but no connection. Try connecting now... qCInfo(dcNymeaConnection()) << "There's a host but no connection. Trying to connect now..."; - connectInternal(m_currentHost); + //connectInternal(m_currentHost); } } @@ -493,7 +463,7 @@ void NymeaConnection::connectInternal(NymeaHost *host) connectInternal(loopbackConnection); } else if (m_networkReachabilityMonitor->availableBearerTypes().testFlag(NymeaConnection::BearerTypeWiFi) - || m_networkReachabilityMonitor->availableBearerTypes().testFlag(NymeaConnection::BearerTypeEthernet)) { + || m_networkReachabilityMonitor->availableBearerTypes().testFlag(NymeaConnection::BearerTypeEthernet)) { Connection* lanConnection = host->connections()->bestMatch(Connection::BearerTypeLan | Connection::BearerTypeWan); if (lanConnection) { qCDebug(dcNymeaConnection()) << "Best candidate LAN/WAN connection:" << lanConnection->url(); @@ -554,44 +524,17 @@ bool NymeaConnection::connectInternal(Connection *connection) return newTransport->connect(connection->url()); } -//NymeaConnection::BearerType NymeaConnection::qBearerTypeToNymeaBearerType(QNetworkConfiguration::BearerType type) const -//{ -// switch (type) { -// case QNetworkConfiguration::BearerUnknown: -// // Unable to determine the connection type. Assume it's something we can establish any connection type on -// return BearerTypeAll; -// case QNetworkConfiguration::BearerEthernet: -// return BearerTypeEthernet; -// case QNetworkConfiguration::BearerWLAN: -// return BearerTypeWiFi; -// case QNetworkConfiguration::Bearer2G: -// case QNetworkConfiguration::BearerCDMA2000: -// case QNetworkConfiguration::BearerWCDMA: -// case QNetworkConfiguration::BearerHSPA: -// case QNetworkConfiguration::BearerWiMAX: -// case QNetworkConfiguration::BearerEVDO: -// case QNetworkConfiguration::BearerLTE: -// case QNetworkConfiguration::Bearer3G: -// case QNetworkConfiguration::Bearer4G: -// return BearerTypeMobileData; -// case QNetworkConfiguration::BearerBluetooth: -// // Note: Do not confuse this with the Bluetooth transport... For Qt, this means IP over BT, not RFCOMM as we do it. -// return BearerTypeNone; -// } -// return BearerTypeAll; -//} - bool NymeaConnection::isConnectionBearerAvailable(Connection::BearerType connectionBearerType) const { switch (connectionBearerType) { case Connection::BearerTypeLan: return availableBearerTypes().testFlag(BearerTypeEthernet) - || availableBearerTypes().testFlag(BearerTypeWiFi); + || availableBearerTypes().testFlag(BearerTypeWiFi); case Connection::BearerTypeWan: case Connection::BearerTypeCloud: return availableBearerTypes().testFlag(BearerTypeEthernet) - || availableBearerTypes().testFlag(BearerTypeWiFi) - || availableBearerTypes().testFlag(BearerTypeMobileData); + || availableBearerTypes().testFlag(BearerTypeWiFi) + || availableBearerTypes().testFlag(BearerTypeMobileData); case Connection::BearerTypeBluetooth: return availableBearerTypes().testFlag(BearerTypeBluetooth); case Connection::BearerTypeUnknown: diff --git a/libnymea-app/connection/nymeaconnection.h b/libnymea-app/connection/nymeaconnection.h index 9a19269c..43c6d323 100644 --- a/libnymea-app/connection/nymeaconnection.h +++ b/libnymea-app/connection/nymeaconnection.h @@ -30,9 +30,14 @@ #include #include #include -//#include #include +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +#include +#else +#include +#endif + #include "nymeahost.h" class NymeaTransportInterface; @@ -125,8 +130,7 @@ private: private: ConnectionStatus m_connectionStatus = ConnectionStatusUnconnected; -// QNetworkConfigurationManager *m_networkConfigManager = nullptr; - NymeaConnection::BearerTypes m_availableBearerTypes = BearerTypeNone; + NetworkReachabilityMonitor *m_networkReachabilityMonitor = nullptr; QHash m_transportFactories; QHash m_transportCandidates; diff --git a/libnymea-app/connection/nymeahosts.cpp b/libnymea-app/connection/nymeahosts.cpp index fcf33920..cea61434 100644 --- a/libnymea-app/connection/nymeahosts.cpp +++ b/libnymea-app/connection/nymeahosts.cpp @@ -23,9 +23,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "nymeahosts.h" -#include "connection/discovery/nymeadiscovery.h" #include "nymeahost.h" -#include "jsonrpc/jsonrpcclient.h" + #include NymeaHosts::NymeaHosts(QObject *parent) : diff --git a/libnymea-app/connection/nymeahosts.h b/libnymea-app/connection/nymeahosts.h index 1ebdb15f..6ad61ad6 100644 --- a/libnymea-app/connection/nymeahosts.h +++ b/libnymea-app/connection/nymeahosts.h @@ -29,8 +29,11 @@ #include #include #include + #include "nymeahost.h" + class JsonRpcClient; +class NymeaDiscovery; class NymeaHosts : public QAbstractListModel { @@ -74,49 +77,49 @@ private: QList m_hosts; }; -class NymeaHostsFilterModel: public QSortFilterProxyModel -{ - Q_OBJECT - Q_PROPERTY(int count READ rowCount NOTIFY countChanged) - Q_PROPERTY(NymeaDiscovery* discovery READ discovery WRITE setDiscovery NOTIFY discoveryChanged) - Q_PROPERTY(JsonRpcClient* jsonRpcClient READ jsonRpcClient WRITE setJsonRpcClient NOTIFY jsonRpcClientChanged) - Q_PROPERTY(bool showUnreachableBearers READ showUnreachableBearers WRITE setShowUnreachableBearers NOTIFY showUnreachableBearersChanged) - Q_PROPERTY(bool showUnreachableHosts READ showUnreachableHosts WRITE setShowUnreachableHosts NOTIFY showUnreachableHostsChanged) +// class NymeaHostsFilterModel: public QSortFilterProxyModel +// { +// Q_OBJECT +// Q_PROPERTY(int count READ rowCount NOTIFY countChanged) +// Q_PROPERTY(NymeaDiscovery* discovery READ discovery WRITE setDiscovery NOTIFY discoveryChanged) +// Q_PROPERTY(JsonRpcClient* jsonRpcClient READ jsonRpcClient WRITE setJsonRpcClient NOTIFY jsonRpcClientChanged) +// Q_PROPERTY(bool showUnreachableBearers READ showUnreachableBearers WRITE setShowUnreachableBearers NOTIFY showUnreachableBearersChanged) +// Q_PROPERTY(bool showUnreachableHosts READ showUnreachableHosts WRITE setShowUnreachableHosts NOTIFY showUnreachableHostsChanged) -public: - NymeaHostsFilterModel(QObject *parent = nullptr); +// public: +// NymeaHostsFilterModel(QObject *parent = nullptr); - NymeaDiscovery *discovery() const; - void setDiscovery(NymeaDiscovery *discovery); +// NymeaDiscovery *discovery() const; +// void setDiscovery(NymeaDiscovery *discovery); - JsonRpcClient *jsonRpcClient() const; - void setJsonRpcClient(JsonRpcClient* jsonRpcClient); +// JsonRpcClient *jsonRpcClient() const; +// void setJsonRpcClient(JsonRpcClient* jsonRpcClient); - bool showUnreachableBearers() const; - void setShowUnreachableBearers(bool showUnreachableBearers); +// bool showUnreachableBearers() const; +// void setShowUnreachableBearers(bool showUnreachableBearers); - bool showUnreachableHosts() const; - void setShowUnreachableHosts(bool showUnreachableHosts); +// bool showUnreachableHosts() const; +// void setShowUnreachableHosts(bool showUnreachableHosts); - Q_INVOKABLE NymeaHost* get(int index) const; +// Q_INVOKABLE NymeaHost *get(int index) const; -signals: - void countChanged(); - void discoveryChanged(); - void jsonRpcClientChanged(); - void showUnreachableBearersChanged(); - void showUnreachableHostsChanged(); +// signals: +// void countChanged(); +// void discoveryChanged(); +// void jsonRpcClientChanged(); +// void showUnreachableBearersChanged(); +// void showUnreachableHostsChanged(); -protected: - bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; +// protected: +// bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; -private: - NymeaDiscovery *m_nymeaDiscovery = nullptr; - JsonRpcClient *m_jsonRpcClient = nullptr; +// private: +// NymeaDiscovery *m_nymeaDiscovery = nullptr; +// JsonRpcClient *m_jsonRpcClient = nullptr; - bool m_showUneachableBearers = false; - bool m_showUneachableHosts = false; +// bool m_showUneachableBearers = false; +// bool m_showUneachableHosts = false; -}; +// }; #endif // NYMEAHOSTS_H diff --git a/libnymea-app/connection/tunnelproxytransport.cpp b/libnymea-app/connection/tunnelproxytransport.cpp index cde06016..3ff9ffa1 100644 --- a/libnymea-app/connection/tunnelproxytransport.cpp +++ b/libnymea-app/connection/tunnelproxytransport.cpp @@ -59,7 +59,7 @@ bool TunnelProxyTransport::connect(const QUrl &url) serverUrl.setScheme(url.scheme() == "tunnels" ? "ssl" : "tcp"); serverUrl.setHost(url.host()); serverUrl.setPort(url.port()); - QUuid serverUuid = QUrlQuery(url).queryItemValue("uuid"); + QUuid serverUuid(QUrlQuery(url).queryItemValue("uuid")); return m_remoteConnection->connectServer(serverUrl, serverUuid); } diff --git a/libnymea-app/engine.cpp b/libnymea-app/engine.cpp index 10bb3b6a..9e39d24c 100644 --- a/libnymea-app/engine.cpp +++ b/libnymea-app/engine.cpp @@ -48,21 +48,6 @@ Engine::Engine(QObject *parent) : connect(m_thingManager, &ThingManager::fetchingDataChanged, this, &Engine::onThingManagerFetchingChanged); - connect(m_jsonRpcClient, &JsonRpcClient::connectedChanged, this, [this]() { - qDebug() << "JSONRpc connected changed:" << m_jsonRpcClient->connected() << "AWS status:" << AWSClient::instance()->awsDevices()->rowCount(); - if (m_jsonRpcClient->connected() && m_jsonRpcClient->cloudConnectionState() == JsonRpcClient::CloudConnectionStateConnected) { - if (AWSClient::instance()->awsDevices()->getDevice(m_jsonRpcClient->serverUuid().toString()) == nullptr) { - m_jsonRpcClient->setupRemoteAccess(AWSClient::instance()->idToken(), AWSClient::instance()->userId()); - } - } - }); - connect(m_jsonRpcClient, &JsonRpcClient::cloudConnectionStateChanged, this, [this](){ - if (m_jsonRpcClient->connected() && m_jsonRpcClient->cloudConnectionState() == JsonRpcClient::CloudConnectionStateConnected) { - if (AWSClient::instance()->awsDevices()->getDevice(m_jsonRpcClient->serverUuid().toString()) == nullptr) { - m_jsonRpcClient->setupRemoteAccess(AWSClient::instance()->idToken(), AWSClient::instance()->userId()); - } - } - }); } ThingManager *Engine::thingManager() const @@ -105,22 +90,6 @@ SystemController *Engine::systemController() const return m_systemController; } -void Engine::deployCertificate() -{ - if (!m_jsonRpcClient->connected()) { - qWarning() << "JSONRPC not connected. Cannot deploy certificate"; - return; - } - if (!AWSClient::instance()->isLoggedIn()) { - qWarning() << "Not logged in at AWS. Cannot deploy certificate"; - return; - } - AWSClient::instance()->fetchCertificate(m_jsonRpcClient->serverUuid().toString(), [this](const QByteArray &rootCA, const QByteArray &certificate, const QByteArray &publicKey, const QByteArray &privateKey, const QString &endpoint){ - qDebug() << "Certificate received" << certificate << publicKey << privateKey; - m_jsonRpcClient->deployCertificate(rootCA, certificate, publicKey, privateKey, endpoint); - }); -} - void Engine::onConnectedChanged() { qDebug() << "Engine: connected changed:" << m_jsonRpcClient->connected(); diff --git a/libnymea-app/interfacesmodel.cpp b/libnymea-app/interfacesmodel.cpp index 8e1e9880..e91a5067 100644 --- a/libnymea-app/interfacesmodel.cpp +++ b/libnymea-app/interfacesmodel.cpp @@ -154,10 +154,10 @@ void InterfacesModel::syncInterfaces() } } - qWarning() << "syncing for interfaces:" << m_shownInterfaces; + // qWarning() << "syncing for interfaces:" << m_shownInterfaces; QStringList interfacesInSource; foreach (ThingClass *dc, thingClasses) { -// qWarning() << "thing" <name() << "has interfaces" << dc->interfaces(); + // qWarning() << "thing" <name() << "has interfaces" << dc->interfaces(); bool isInShownIfaces = false; foreach (const QString &interface, dc->interfaces()) { @@ -168,7 +168,7 @@ void InterfacesModel::syncInterfaces() if (!interfacesInSource.contains(interface)) { interfacesInSource.append(interface); } -// qWarning() << "yes" << interface; + // qWarning() << "yes" << interface; isInShownIfaces = true; } if (m_showUncategorized && !isInShownIfaces && !interfacesInSource.contains("uncategorized")) { diff --git a/libnymea-app/jsonrpc/jsonrpcclient.cpp b/libnymea-app/jsonrpc/jsonrpcclient.cpp index 9dcbf913..29c317be 100644 --- a/libnymea-app/jsonrpc/jsonrpcclient.cpp +++ b/libnymea-app/jsonrpc/jsonrpcclient.cpp @@ -307,7 +307,7 @@ QString JsonRpcClient::jsonRpcVersion() const QUuid JsonRpcClient::serverUuid() const { - return m_connection && m_connection->currentHost() ? m_connection->currentHost()->uuid().toString() : ""; + return m_connection && m_connection->currentHost() ? m_connection->currentHost()->uuid() : QUuid(); } QString JsonRpcClient::serverName() const diff --git a/libnymea-app/libnymea-app.pri b/libnymea-app/libnymea-app.pri index 72ff5352..693acf2c 100644 --- a/libnymea-app/libnymea-app.pri +++ b/libnymea-app/libnymea-app.pri @@ -11,7 +11,6 @@ include(../nymea-remoteproxy/libnymea-remoteproxyclient/libnymea-remoteproxyclient.pri) - QT -= gui QT += network websockets bluetooth charts quick diff --git a/libnymea-app/models/boolseriesadapter.cpp b/libnymea-app/models/boolseriesadapter.cpp index d12f9164..37b70cdb 100644 --- a/libnymea-app/models/boolseriesadapter.cpp +++ b/libnymea-app/models/boolseriesadapter.cpp @@ -46,12 +46,12 @@ void BoolSeriesAdapter::setLogsModel(LogsModel *logsModel) } -QtCharts::QXYSeries *BoolSeriesAdapter::xySeries() const +QXYSeries *BoolSeriesAdapter::xySeries() const { return m_series; } -void BoolSeriesAdapter::setXySeries(QtCharts::QXYSeries *series) +void BoolSeriesAdapter::setXySeries(QXYSeries *series) { if (m_series != series) { m_series = series; diff --git a/libnymea-app/models/boolseriesadapter.h b/libnymea-app/models/boolseriesadapter.h index 1ee5720d..a76e9708 100644 --- a/libnymea-app/models/boolseriesadapter.h +++ b/libnymea-app/models/boolseriesadapter.h @@ -34,7 +34,7 @@ class BoolSeriesAdapter : public QObject { Q_OBJECT Q_PROPERTY(LogsModel* logsModel READ logsModel WRITE setLogsModel NOTIFY logsModelChanged) - Q_PROPERTY(QtCharts::QXYSeries* xySeries READ xySeries WRITE setXySeries NOTIFY xySeriesChanged) + Q_PROPERTY(QXYSeries* xySeries READ xySeries WRITE setXySeries NOTIFY xySeriesChanged) Q_PROPERTY(bool inverted READ inverted WRITE setInverted NOTIFY invertedChanged) @@ -44,8 +44,8 @@ public: LogsModel* logsModel() const; void setLogsModel(LogsModel *logsModel); - QtCharts::QXYSeries* xySeries() const; - void setXySeries(QtCharts::QXYSeries *series); + QXYSeries* xySeries() const; + void setXySeries(QXYSeries *series); bool inverted() const; void setInverted(bool inverted); @@ -65,7 +65,7 @@ private: private: LogsModel* m_model = nullptr; - QtCharts::QXYSeries* m_series = nullptr; + QXYSeries* m_series = nullptr; bool m_inverted = false; }; diff --git a/libnymea-app/models/newlogsmodel.cpp b/libnymea-app/models/newlogsmodel.cpp index 8171544c..cb0197c0 100644 --- a/libnymea-app/models/newlogsmodel.cpp +++ b/libnymea-app/models/newlogsmodel.cpp @@ -460,7 +460,7 @@ void NewLogsModel::logsReply(int commandId, const QVariantMap &data) } else { if (!entries.isEmpty()) { beginInsertRows(QModelIndex(), m_list.count(), m_list.count() + entries.count() - 1); - qSort(entries.begin(), entries.end(), [](NewLogEntry *left, NewLogEntry *right){ + std::sort(entries.begin(), entries.end(), [](NewLogEntry *left, NewLogEntry *right){ return left->timestamp() > right->timestamp(); }); m_list.append(entries); diff --git a/libnymea-app/models/newlogsmodel.h b/libnymea-app/models/newlogsmodel.h index cb815ac1..31ac72ab 100644 --- a/libnymea-app/models/newlogsmodel.h +++ b/libnymea-app/models/newlogsmodel.h @@ -25,11 +25,12 @@ #ifndef NEWLOGSMODEL_H #define NEWLOGSMODEL_H -#include +#include #include -#include "newlogentry.h" +#include -class Engine; +#include "engine.h" +#include "newlogentry.h" class NewLogsModel : public QAbstractListModel, public QQmlParserStatus { diff --git a/libnymea-app/models/nymeahostsfiltermodel.h b/libnymea-app/models/nymeahostsfiltermodel.h index 18f800b4..3ee0feb6 100644 --- a/libnymea-app/models/nymeahostsfiltermodel.h +++ b/libnymea-app/models/nymeahostsfiltermodel.h @@ -3,8 +3,8 @@ #include -#include "connection/discovery/nymeadiscovery.h" #include "jsonrpc/jsonrpcclient.h" +#include "connection/discovery/nymeadiscovery.h" class NymeaHostsFilterModel: public QSortFilterProxyModel { diff --git a/libnymea-app/pluginconfigmanager.cpp b/libnymea-app/pluginconfigmanager.cpp index b749be3c..49277446 100644 --- a/libnymea-app/pluginconfigmanager.cpp +++ b/libnymea-app/pluginconfigmanager.cpp @@ -85,7 +85,7 @@ void PluginConfigManager::getPluginConfigResponse(int /*commandId*/, const QVari QVariantList pluginParams = params.value("configuration").toList(); foreach (const QVariant ¶mVariant, pluginParams) { Param* param = new Param(); - param->setParamTypeId(paramVariant.toMap().value("paramTypeId").toString()); + param->setParamTypeId(paramVariant.toMap().value("paramTypeId").toUuid()); param->setValue(paramVariant.toMap().value("value")); m_params->addParam(param); } diff --git a/libnymea-app/scripting/codecompletion.cpp b/libnymea-app/scripting/codecompletion.cpp index 08b1330d..190a0d45 100644 --- a/libnymea-app/scripting/codecompletion.cpp +++ b/libnymea-app/scripting/codecompletion.cpp @@ -237,16 +237,16 @@ void CodeCompletion::update() qDebug() << "stateName block info" << info.name << info.properties; QString thingId; Interfaces ifaces; - StateTypes *stateTypes = nullptr; + //StateTypes *stateTypes = nullptr; if (info.properties.contains("thingId")) { thingId = info.properties.value("thingId"); qDebug() << "selected thingId" << thingId; - Thing *thing = m_engine->thingManager()->things()->getThing(thingId); + Thing *thing = m_engine->thingManager()->things()->getThing(QUuid(thingId)); if (!thing) { return; } - stateTypes = thing->thingClass()->stateTypes(); + //stateTypes = thing->thingClass()->stateTypes(); } else if (info.properties.contains("interfaceName")) { QString interfaceName = info.properties.value("interfaceName"); @@ -254,7 +254,7 @@ void CodeCompletion::update() if (!iface) { return; } - stateTypes = iface->stateTypes(); + //stateTypes = iface->stateTypes(); } else { return; } diff --git a/libnymea-app/serverdebug/serverdebugmanager.cpp b/libnymea-app/serverdebug/serverdebugmanager.cpp index 882e6fe1..be695c45 100644 --- a/libnymea-app/serverdebug/serverdebugmanager.cpp +++ b/libnymea-app/serverdebug/serverdebugmanager.cpp @@ -24,9 +24,7 @@ #include "serverdebugmanager.h" -#include "engine.h" #include "logging.h" -#include "serverloggingcategories.h" NYMEA_LOGGING_CATEGORY(dcServerDebug, "ServerDebug") diff --git a/libnymea-app/serverdebug/serverdebugmanager.h b/libnymea-app/serverdebug/serverdebugmanager.h index 2603cf08..573c126b 100644 --- a/libnymea-app/serverdebug/serverdebugmanager.h +++ b/libnymea-app/serverdebug/serverdebugmanager.h @@ -27,17 +27,16 @@ #include -#include "serverloggingcategory.h" +#include "engine.h" +#include "serverloggingcategories.h" -class Engine; class JsonRpcClient; -class ServerLoggingCategories; class ServerDebugManager : public QObject { Q_OBJECT - Q_PROPERTY(Engine* engine READ engine WRITE setEngine NOTIFY engineChanged) - Q_PROPERTY(bool fetchingData READ fetchingData NOTIFY fetchingDataChanged) + Q_PROPERTY(Engine* engine READ engine WRITE setEngine NOTIFY engineChanged FINAL) + Q_PROPERTY(bool fetchingData READ fetchingData NOTIFY fetchingDataChanged FINAL) Q_PROPERTY(ServerLoggingCategories *categories READ categories CONSTANT FINAL) public: diff --git a/libnymea-app/zigbee/zigbeenode.cpp b/libnymea-app/zigbee/zigbeenode.cpp index 06ce0a29..a007bc62 100644 --- a/libnymea-app/zigbee/zigbeenode.cpp +++ b/libnymea-app/zigbee/zigbeenode.cpp @@ -25,6 +25,7 @@ #include "zigbeenode.h" #include +#include ZigbeeNode::ZigbeeNode(const QUuid &networkUuid, const QString &ieeeAddress, QObject *parent) : QObject(parent), @@ -666,7 +667,7 @@ QString ZigbeeCluster::clusterName() const QMetaEnum clusterEnum = QMetaEnum::fromType(); QString name = clusterEnum.valueToKey(m_clusterId); name.remove("ZigbeeClusterId"); - QRegExp re1 = QRegExp("([A-Z])([a-z]*)"); + QRegularExpression re1 = QRegularExpression("([A-Z])([a-z]*)"); name.replace(re1, ";\\1\\2"); QStringList parts = name.split(";"); QString clusterName = parts.join(" ").trimmed(); diff --git a/libnymea-app/zwave/zwavemanager.cpp b/libnymea-app/zwave/zwavemanager.cpp index 21bf6359..b72f9d98 100644 --- a/libnymea-app/zwave/zwavemanager.cpp +++ b/libnymea-app/zwave/zwavemanager.cpp @@ -27,12 +27,9 @@ #include #include -#include "types/serialports.h" #include "types/serialport.h" -#include "zwavenetwork.h" -#include "zwavenode.h" -#include "engine.h" + #include "logging.h" NYMEA_LOGGING_CATEGORY(dcZWave, "ZWave") diff --git a/libnymea-app/zwave/zwavemanager.h b/libnymea-app/zwave/zwavemanager.h index b15d2139..18ad8efa 100644 --- a/libnymea-app/zwave/zwavemanager.h +++ b/libnymea-app/zwave/zwavemanager.h @@ -28,22 +28,21 @@ #include #include -class Engine; +#include "engine.h" +#include "zwavenetwork.h" +#include "types/serialports.h" + class JsonRpcClient; -class SerialPorts; -class ZWaveNetwork; -class ZWaveNetworks; -class ZWaveNode; class ZWaveManager : public QObject { Q_OBJECT - Q_PROPERTY(Engine* engine READ engine WRITE setEngine NOTIFY engineChanged) - Q_PROPERTY(bool fetchingData READ fetchingData NOTIFY fetchingDataChanged) - Q_PROPERTY(bool zwaveAvailable READ zwaveAvailable NOTIFY zwaveAvailableChanged) + Q_PROPERTY(Engine *engine READ engine WRITE setEngine NOTIFY engineChanged FINAL) + Q_PROPERTY(bool fetchingData READ fetchingData NOTIFY fetchingDataChanged FINAL) + Q_PROPERTY(bool zwaveAvailable READ zwaveAvailable NOTIFY zwaveAvailableChanged FINAL) - Q_PROPERTY(SerialPorts *serialPorts READ serialPorts CONSTANT) - Q_PROPERTY(ZWaveNetworks *networks READ networks CONSTANT) + Q_PROPERTY(SerialPorts *serialPorts READ serialPorts CONSTANT FINAL) + Q_PROPERTY(ZWaveNetworks *networks READ networks CONSTANT FINAL) public: enum ZWaveError { @@ -111,7 +110,7 @@ private: Q_INVOKABLE void notificationReceived(const QVariantMap &data); private: - Engine* m_engine = nullptr; + Engine *m_engine = nullptr; bool m_fetchingData = false; bool m_zwaveAvailable = false; SerialPorts *m_serialPorts = nullptr; diff --git a/libnymea-app/zwave/zwavenetwork.h b/libnymea-app/zwave/zwavenetwork.h index 90a30925..633b8a66 100644 --- a/libnymea-app/zwave/zwavenetwork.h +++ b/libnymea-app/zwave/zwavenetwork.h @@ -29,23 +29,22 @@ #include #include -class ZWaveNode; -class ZWaveNodes; +#include "zwavenode.h" class ZWaveNetwork : public QObject { Q_OBJECT - Q_PROPERTY(QUuid networkUuid READ networkUuid CONSTANT) - Q_PROPERTY(QString serialPort READ serialPort CONSTANT) - Q_PROPERTY(quint32 homeId READ homeId NOTIFY homeIdChanged) - Q_PROPERTY(bool isZWavePlus READ isZWavePlus NOTIFY isZWavePlusChanged) - Q_PROPERTY(bool isPrimaryController READ isPrimaryController NOTIFY isPrimaryControllerChanged) - Q_PROPERTY(bool isStaticUpdateController READ isStaticUpdateController NOTIFY isStaticUpdateControllerChanged) - Q_PROPERTY(bool isBridgeController READ isBridgeController NOTIFY isBridgeControllerChanged) - Q_PROPERTY(bool waitingForNodeAddition READ waitingForNodeAddition NOTIFY waitingForNodeAdditionChanged) - Q_PROPERTY(bool waitingForNodeRemoval READ waitingForNodeRemoval NOTIFY waitingForNodeRemovalChanged) - Q_PROPERTY(ZWaveNetworkState networkState READ networkState NOTIFY networkStateChanged) - Q_PROPERTY(ZWaveNodes* nodes READ nodes CONSTANT) + Q_PROPERTY(QUuid networkUuid READ networkUuid CONSTANT FINAL) + Q_PROPERTY(QString serialPort READ serialPort CONSTANT FINAL) + Q_PROPERTY(quint32 homeId READ homeId NOTIFY homeIdChanged FINAL) + Q_PROPERTY(bool isZWavePlus READ isZWavePlus NOTIFY isZWavePlusChanged FINAL) + Q_PROPERTY(bool isPrimaryController READ isPrimaryController NOTIFY isPrimaryControllerChanged FINAL) + Q_PROPERTY(bool isStaticUpdateController READ isStaticUpdateController NOTIFY isStaticUpdateControllerChanged FINAL) + Q_PROPERTY(bool isBridgeController READ isBridgeController NOTIFY isBridgeControllerChanged FINAL) + Q_PROPERTY(bool waitingForNodeAddition READ waitingForNodeAddition NOTIFY waitingForNodeAdditionChanged FINAL) + Q_PROPERTY(bool waitingForNodeRemoval READ waitingForNodeRemoval NOTIFY waitingForNodeRemovalChanged FINAL) + Q_PROPERTY(ZWaveNetworkState networkState READ networkState NOTIFY networkStateChanged FINAL) + Q_PROPERTY(ZWaveNodes* nodes READ nodes CONSTANT FINAL) public: enum ZWaveNetworkState { @@ -55,6 +54,7 @@ public: ZWaveNetworkStateError }; Q_ENUM(ZWaveNetworkState) + explicit ZWaveNetwork(const QUuid &networkUuid, const QString &serialPort, QObject *parent = nullptr); QUuid networkUuid() const; @@ -119,6 +119,7 @@ class ZWaveNetworks: public QAbstractListModel { Q_OBJECT Q_PROPERTY(int count READ rowCount NOTIFY countChanged) + public: enum Roles { RoleUuid, @@ -141,14 +142,14 @@ public: void addNetwork(ZWaveNetwork *network); void removeNetwork(const QUuid &networkUuid); - Q_INVOKABLE ZWaveNetwork* get(int index) const; - Q_INVOKABLE ZWaveNetwork* getNetwork(const QUuid &networkUuid); + Q_INVOKABLE ZWaveNetwork *get(int index) const; + Q_INVOKABLE ZWaveNetwork *getNetwork(const QUuid &networkUuid); signals: void countChanged(); private: - QList m_list; + QList m_list; }; #endif // ZWAVENETWORK_H diff --git a/libnymea-app/zwave/zwavenode.cpp b/libnymea-app/zwave/zwavenode.cpp index d6b301f3..abff9941 100644 --- a/libnymea-app/zwave/zwavenode.cpp +++ b/libnymea-app/zwave/zwavenode.cpp @@ -24,6 +24,7 @@ #include "zwavenode.h" #include +#include ZWaveNode::ZWaveNode(const QUuid &networkUuid, quint8 id, QObject *parent): QObject{parent}, @@ -59,7 +60,7 @@ void ZWaveNode::setNodeType(ZWaveNodeType nodeType) QString ZWaveNode::nodeTypeString() const { QMetaEnum metaEnum = QMetaEnum::fromType(); - return QString(metaEnum.valueToKey(m_nodeType)).remove(QRegExp("^ZWaveNodeType")); + return QString(metaEnum.valueToKey(m_nodeType)).remove(QRegularExpression("^ZWaveNodeType")); } ZWaveNode::ZWaveNodeRole ZWaveNode::role() const @@ -78,7 +79,7 @@ void ZWaveNode::setRole(ZWaveNodeRole role) QString ZWaveNode::roleString() const { QMetaEnum metaEnum = QMetaEnum::fromType(); - return QString(metaEnum.valueToKey(m_role)).remove(QRegExp("^ZWaveNodeRole")); + return QString(metaEnum.valueToKey(m_role)).remove(QRegularExpression("^ZWaveNodeRole")); } ZWaveNode::ZWaveDeviceType ZWaveNode::deviceType() const @@ -94,7 +95,7 @@ void ZWaveNode::setDeviceType(ZWaveDeviceType deviceType) QString ZWaveNode::deviceTypeString() const { QMetaEnum metaEnum = QMetaEnum::fromType(); - return QString(metaEnum.valueToKey(m_deviceType)).remove(QRegExp("^ZWaveDeviceType")); + return QString(metaEnum.valueToKey(m_deviceType)).remove(QRegularExpression("^ZWaveDeviceType")); } quint16 ZWaveNode::manufacturerId() const diff --git a/nymea-app.pro b/nymea-app.pro index 65810c03..e1e53824 100644 --- a/nymea-app.pro +++ b/nymea-app.pro @@ -81,9 +81,6 @@ linux:!android: { android: { message("Android package source dir $${ANDROID_PACKAGE_SOURCE_DIR}") - SUBDIRS += androidservice - androidservice.depends = libnymea-app - NYMEA_APP_ROOT_PROPERTY="nymeaAppRoot=$${top_srcdir}" no-firebase: FIREBASE_PROPERTY="useFirebase=false" else: FIREBASE_PROPERTY="useFirebase=true" diff --git a/nymea-app/CMakeLists.txt b/nymea-app/CMakeLists.txt new file mode 100644 index 00000000..f844da89 --- /dev/null +++ b/nymea-app/CMakeLists.txt @@ -0,0 +1,153 @@ +set(NYMEA_APP_SOURCES + main.cpp + configuredhostsmodel.cpp + dashboard/dashboarditem.cpp + dashboard/dashboardmodel.cpp + mouseobserver.cpp + nfchelper.cpp + nfcthingactionwriter.cpp + platformintegration/platformpermissions.cpp + stylecontroller.cpp + pushnotifications.cpp + platformhelper.cpp + platformintegration/generic/screenhelper.cpp + utils/privacypolicyhelper.cpp + utils/qhashqml.cpp +) + +set(NYMEA_APP_HEADERS + configuredhostsmodel.h + dashboard/dashboarditem.h + dashboard/dashboardmodel.h + mouseobserver.h + nfchelper.h + nfcthingactionwriter.h + platformintegration/generic/screenhelper.h + platformintegration/platformpermissions.h + stylecontroller.h + pushnotifications.h + platformhelper.h + ruletemplates/messages.h + utils/privacypolicyhelper.h + utils/qhashqml.h +) + +if(UNIX AND NOT APPLE AND NOT ANDROID) + list(APPEND NYMEA_APP_SOURCES + platformintegration/generic/platformhelpergeneric.cpp + ) + list(APPEND NYMEA_APP_HEADERS + platformintegration/generic/platformhelpergeneric.h + ) +endif() + +if(ANDROID) + list(APPEND NYMEA_APP_SOURCES + platformintegration/android/platformhelperandroid.cpp + platformintegration/android/platformpermissionsandroid.cpp + ) + list(APPEND NYMEA_APP_HEADERS + platformintegration/android/platformhelperandroid.h + platformintegration/android/platformpermissionsandroid.h + ) +endif() + +set(NYMEA_APP_RESOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/resources.qrc + ${CMAKE_CURRENT_SOURCE_DIR}/ruletemplates.qrc + ${CMAKE_CURRENT_SOURCE_DIR}/images.qrc +) + +if(NYMEA_OVERLAY_PATH) + message(WARNING "Overlay support is not implemented in the CMake build yet; NYMEA_OVERLAY_PATH will be ignored.") +else() + list(APPEND NYMEA_APP_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/styles.qrc) +endif() + +if(NYMEA_USE_MATERIAL_ICONS) + list(APPEND NYMEA_APP_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/ui/icons/material/icons.qrc) +else() + list(APPEND NYMEA_APP_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/ui/icons/suru/icons.qrc) +endif() + +qt_add_executable(nymea-app + MANUAL_FINALIZATION + ${NYMEA_APP_SOURCES} + ${NYMEA_APP_HEADERS} + ${NYMEA_APP_RESOURCES} +) + +target_include_directories(nymea-app + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/libnymea-app + ${CMAKE_SOURCE_DIR}/experiences/airconditioning + ${CMAKE_BINARY_DIR} +) + +target_link_libraries(nymea-app + PRIVATE + nymea-app-core + nymea-app-airconditioning + Qt6::Gui + Qt6::Network + Qt6::Qml + Qt6::Quick + Qt6::QuickControls2 + Qt6::Svg + Qt6::WebSockets + Qt6::Bluetooth + Qt6::Charts + Qt6::Nfc +) + +if(TARGET Qt6::WebView) + target_link_libraries(nymea-app PRIVATE Qt6::WebView) + target_compile_definitions(nymea-app PRIVATE HAVE_WEBVIEW) +endif() + +find_package(Qt6 COMPONENTS GuiPrivate QUIET) +if(TARGET Qt6::GuiPrivate) + target_link_libraries(nymea-app PRIVATE Qt6::GuiPrivate) +else() + message(WARNING "Qt6::GuiPrivate not found; continuing without private GUI APIs.") +endif() + +if(UNIX AND NOT APPLE AND NYMEA_ENABLE_ZEROCONF) + find_package(PkgConfig REQUIRED) + pkg_check_modules(AVAHI REQUIRED IMPORTED_TARGET avahi-client avahi-common) + target_link_libraries(nymea-app PRIVATE PkgConfig::AVAHI) +endif() + +if(WIN32) + target_compile_definitions(nymea-app PRIVATE NOMINMAX) +endif() + +if(ANDROID) + if(DEFINED NYMEA_ANDROID_PACKAGE_SOURCE_DIR) + set_property(TARGET nymea-app PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR "${NYMEA_ANDROID_PACKAGE_SOURCE_DIR}") + endif() + + set_property(TARGET nymea-app PROPERTY QT_ANDROID_MIN_SDK_VERSION 23) + set_property(TARGET nymea-app PROPERTY QT_ANDROID_TARGET_SDK_VERSION 35) + + if(NYMEA_ENABLE_FIREBASE) + target_compile_definitions(nymea-app PRIVATE WITH_FIREBASE) + target_include_directories(nymea-app PRIVATE ${CMAKE_SOURCE_DIR}/3rdParty/android/firebase_cpp_sdk/include) + + if(CMAKE_ANDROID_ARCH_ABI) + set(_firebase_lib_dir "${CMAKE_SOURCE_DIR}/3rdParty/android/firebase_cpp_sdk/libs/android/${CMAKE_ANDROID_ARCH_ABI}/c++") + target_link_libraries(nymea-app PRIVATE + "${_firebase_lib_dir}/libfirebase_messaging.a" + "${_firebase_lib_dir}/libfirebase_app.a" + ) + else() + message(WARNING "CMAKE_ANDROID_ARCH_ABI is not defined; Firebase static libraries could not be linked.") + endif() + else() + message(STATUS "Firebase support disabled via NYMEA_ENABLE_FIREBASE option.") + endif() +endif() + +qt_finalize_executable(nymea-app) + diff --git a/nymea-app/configuredhostsmodel.cpp b/nymea-app/configuredhostsmodel.cpp index c4a08dcf..843e5be6 100644 --- a/nymea-app/configuredhostsmodel.cpp +++ b/nymea-app/configuredhostsmodel.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include Q_DECLARE_LOGGING_CATEGORY(dcApplication) @@ -154,8 +155,8 @@ void ConfiguredHostsModel::removeHost(int index) settings.remove(""); settings.endGroup(); - QDir dir(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/sslcerts/"); - QFile certFile(dir.absoluteFilePath(hostUuidString.remove(QRegExp("[{}]")) + ".pem")); + QDir dir(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/sslcerts/"); + QFile certFile(dir.absoluteFilePath(hostUuidString.remove(QRegularExpression("[{}]")) + ".pem")); if (certFile.exists()) { if (!certFile.remove()) { qCWarning(dcApplication()) << "Failed to remove certificate file" << certFile.fileName() << certFile.errorString(); diff --git a/nymea-app/main.cpp b/nymea-app/main.cpp index 6fc679c7..bd0ff131 100644 --- a/nymea-app/main.cpp +++ b/nymea-app/main.cpp @@ -39,6 +39,10 @@ #include #include +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +#include +#endif + #include "libnymea-app-core.h" #include "libnymea-app-airconditioning.h" @@ -53,8 +57,9 @@ #include "dashboard/dashboarditem.h" #include "mouseobserver.h" #include "configuredhostsmodel.h" -#include "../config.h" +#include "utils/qhashqml.h" #include "utils/privacypolicyhelper.h" +#include "config.h" #include "logging.h" @@ -71,10 +76,7 @@ int main(int argc, char *argv[]) #ifdef Q_OS_OSX qputenv("QT_WEBVIEW_PLUGIN", "native"); #endif - - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication application(argc, argv); - application.setApplicationName(APPLICATION_NAME); application.setOrganizationName(ORGANISATION_NAME); @@ -114,8 +116,11 @@ int main(int argc, char *argv[]) } } - QTranslator qtTranslator; - qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); + QTranslator qtTranslator; + if (!qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::path(QLibraryInfo::TranslationsPath))) { + qCWarning(dcApplication()) << "Unable to load translations from" << QLibraryInfo::path(QLibraryInfo::TranslationsPath); + } + application.installTranslator(&qtTranslator); QStringList loadedTranslations; @@ -169,6 +174,21 @@ int main(int argc, char *argv[]) QFontDatabase::addApplicationFont(fi.absoluteFilePath()); } +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + // Note: QNetworkInformation should always first be loaded in the same thread as the QCoreApplication object + qCInfo(dcApplication()) << "Available network information backends" << QNetworkInformation::instance()->availableBackends(); + + if (QNetworkInformation::instance()->loadDefaultBackend()) { + qCInfo(dcApplication()) << "Loaded default network information backend" << QNetworkInformation::instance()->backendName(); + qCInfo(dcApplication()) << "Network infromation supported features:" << QNetworkInformation::instance()->supportedFeatures(); + qCInfo(dcApplication()) << "Network reachability:" << QNetworkInformation::instance()->reachability(); + qCInfo(dcApplication()) << "Network trasport medium changed:" << QNetworkInformation::instance()->transportMedium(); + + } else { + qCWarning(dcApplication()) << "Unable to load default network information backend." << QNetworkInformation::instance()->availableBackends(); + } +#endif + qmlRegisterSingletonType(QUrl("qrc:///styles/" + styleController.currentStyle() + "/Style.qml"), "Nymea", 1, 0, "Style" ); qmlRegisterType(QUrl("qrc:///styles/" + styleController.currentStyle() + "/Background.qml"), "Nymea", 1, 0, "Background" ); qmlRegisterSingletonType(QUrl("qrc:///ui/Configuration.qml"), "Nymea", 1, 0, "Configuration"); diff --git a/nymea-app/nymea-app.pro b/nymea-app/nymea-app.pro index b4c70af2..ffb97878 100644 --- a/nymea-app/nymea-app.pro +++ b/nymea-app/nymea-app.pro @@ -15,8 +15,7 @@ qtHaveModule(webview) { INCLUDEPATH += $$top_srcdir/libnymea-app \ $$top_srcdir/experiences/airconditioning -LIBS += -L$$top_builddir/libnymea-app/ -lnymea-app \ - -L$$top_builddir/experiences/airconditioning -lnymea-app-airconditioning +linux:!android: LIBS += -L$$top_builddir/libnymea-app/ -lnymea-app -L$$top_builddir/experiences/airconditioning -lnymea-app-airconditioning win32:Debug:LIBS += -L$$top_builddir/libnymea-app/debug \ -L$$top_builddir/experiences/airconditioning/debug @@ -92,19 +91,17 @@ android { ANDROID_MIN_SDK_VERSION = 21 ANDROID_TARGET_SDK_VERSION = 35 - QT += androidextras HEADERS += platformintegration/android/platformhelperandroid.h \ platformintegration/android/platformpermissionsandroid.h \ SOURCES += platformintegration/android/platformhelperandroid.cpp \ platformintegration/android/platformpermissionsandroid.cpp \ - # https://bugreports.qt.io/browse/QTBUG-83165 CORE_LIBS += -L$${top_builddir}/libnymea-app/$${ANDROID_TARGET_ARCH} AIRCONDITIONING_LIBS += -L$${top_builddir}/experiences/airconditioning/$${ANDROID_TARGET_ARCH} - LIBS += $${CORE_LIBS} $${AIRCONDITIONING_LIBS} - message("CORE_LIBS: $${CORE_LIBS}") + LIBS += $${CORE_LIBS} -lnymea-app_$${ANDROID_TARGET_ARCH} \ + $${AIRCONDITIONING_LIBS} -lnymea-app-airconditioning_$${ANDROID_TARGET_ARCH} versioninfo.files = ../version.txt versioninfo.path = / @@ -113,9 +110,9 @@ android { DISTFILES += \ $$ANDROID_PACKAGE_SOURCE_DIR/AndroidManifest.xml \ $$ANDROID_PACKAGE_SOURCE_DIR/google-services.json \ - $$ANDROID_PACKAGE_SOURCE_DIR/gradle/wrapper/gradle-wrapper.jar \ $$ANDROID_PACKAGE_SOURCE_DIR/gradlew \ $$ANDROID_PACKAGE_SOURCE_DIR/res/values/libs.xml \ + $$ANDROID_PACKAGE_SOURCE_DIR/res/values/styles.xml \ $$ANDROID_PACKAGE_SOURCE_DIR/build.gradle \ $$ANDROID_PACKAGE_SOURCE_DIR/gradle/wrapper/gradle-wrapper.properties \ $$ANDROID_PACKAGE_SOURCE_DIR/gradlew.bat \ diff --git a/nymea-app/platformhelper.cpp b/nymea-app/platformhelper.cpp index cbe66d52..241f1c88 100644 --- a/nymea-app/platformhelper.cpp +++ b/nymea-app/platformhelper.cpp @@ -32,7 +32,6 @@ #include #if defined Q_OS_ANDROID -#include #include "platformintegration/android/platformhelperandroid.h" #elif defined Q_OS_IOS #include "platformintegration/ios/platformhelperios.h" @@ -70,7 +69,7 @@ void PlatformHelper::notificationActionReceived(const QString &nymeaData) QUrlQuery query(map.value("data").toString()); QVariantMap dataMap; for (int i = 0; i < query.queryItems().count(); i++) { - const QPair &item = query.queryItems().at(i); + QPair item = query.queryItems().at(i); dataMap.insert(item.first, item.second); } map.insert("dataMap", dataMap); diff --git a/nymea-app/platformintegration/android/java/io/guh/nymeaapp/NymeaAppActivity.java b/nymea-app/platformintegration/android/java/io/guh/nymeaapp/NymeaAppActivity.java index 87b31da6..558482a9 100644 --- a/nymea-app/platformintegration/android/java/io/guh/nymeaapp/NymeaAppActivity.java +++ b/nymea-app/platformintegration/android/java/io/guh/nymeaapp/NymeaAppActivity.java @@ -20,8 +20,15 @@ import androidx.core.content.FileProvider; import androidx.core.view.ViewCompat; import androidx.core.view.WindowCompat; import android.view.WindowInsets; +import android.graphics.Insets; -public class NymeaAppActivity extends org.qtproject.qt5.android.bindings.QtActivity +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.res.Resources; + +import org.qtproject.qt.android.bindings.QtActivity; + +public class NymeaAppActivity extends QtActivity { private static final String TAG = "nymea-app: NymeaAppActivity"; private static Context context = null; @@ -42,6 +49,7 @@ public class NymeaAppActivity extends org.qtproject.qt5.android.bindings.QtActiv @Override public void onCreate(Bundle savedInstanceState) { + Log.w(TAG, "Create activity"); super.onCreate(savedInstanceState); // Move th app to the background (Edge to edge is forced since SDK 35) //WindowCompat.setDecorFitsSystemWindows(getWindow(), true); @@ -143,12 +151,62 @@ public class NymeaAppActivity extends org.qtproject.qt5.android.bindings.QtActiv public int topPadding() { WindowInsets windowInsets = getWindow().getDecorView().getRootWindowInsets(); - return windowInsets.getInsets(WindowInsets.Type.statusBars() | WindowInsets.Type.displayCutout()).top; + + if (windowInsets == null) { + return 0; + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + Insets insets = windowInsets.getInsets(WindowInsets.Type.statusBars() | WindowInsets.Type.displayCutout()); + return insets != null ? insets.top : 0; + } + + return windowInsets.getStableInsetTop(); } public int bottomPadding() { WindowInsets windowInsets = getWindow().getDecorView().getRootWindowInsets(); - return windowInsets.getInsets(WindowInsets.Type.navigationBars() | WindowInsets.Type.displayCutout()).bottom; + if (windowInsets == null) { + return 0; + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + Insets insets = windowInsets.getInsets(WindowInsets.Type.navigationBars() | WindowInsets.Type.displayCutout()); + return insets != null ? insets.bottom : 0; + } + + return windowInsets.getStableInsetBottom(); } + private void logStaticInitClassesMetadata() { + try { + ApplicationInfo appInfo = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA); + if (appInfo.metaData == null || !appInfo.metaData.containsKey("android.app.static_init_classes")) { + Log.w(TAG, "No android.app.static_init_classes meta-data present in the manifest"); + return; + } + + Object value = appInfo.metaData.get("android.app.static_init_classes"); + if (!(value instanceof Integer)) { + Log.w(TAG, "android.app.static_init_classes meta-data is not a resource reference: " + value); + return; + } + + int resId = (Integer) value; + if (resId == 0) { + Log.e(TAG, "android.app.static_init_classes meta-data resolves to resource id 0"); + return; + } + + try { + String resName = getResources().getResourceName(resId); + String resValue = getResources().getString(resId); + Log.i(TAG, "android.app.static_init_classes -> " + resName + " = " + resValue); + } catch (Resources.NotFoundException notFoundException) { + Log.e(TAG, "android.app.static_init_classes references missing resource 0x" + Integer.toHexString(resId), notFoundException); + } + } catch (PackageManager.NameNotFoundException exception) { + Log.e(TAG, "Failed to inspect android.app.static_init_classes meta-data", exception); + } + } } diff --git a/nymea-app/platformintegration/android/platformhelperandroid.cpp b/nymea-app/platformintegration/android/platformhelperandroid.cpp index 447c7df3..3ad8a7e3 100644 --- a/nymea-app/platformintegration/android/platformhelperandroid.cpp +++ b/nymea-app/platformintegration/android/platformhelperandroid.cpp @@ -26,10 +26,9 @@ #include #include -#include -#include +#include #include -#include +#include // WindowManager.LayoutParams #define FLAG_TRANSLUCENT_STATUS 0x04000000 @@ -64,20 +63,27 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* /*reserved*/) return JNI_VERSION_1_6; } -static QAndroidJniObject getAndroidWindow() -{ - QAndroidJniObject window = QtAndroid::androidActivity().callObjectMethod("getWindow", "()Landroid/view/Window;"); - return window; -} +// static QJniObject getAndroidWindow() +// { +// QJniObject window; +// QJniObject activity = QNativeInterface::QAndroidApplication::context(); +// if(activity.isValid()) { +// activity.callMethod("setRequestedOrientation", "(I)V", 0); +// window = activity.callObjectMethod("getWindow", "()Landroid/view/Window;"); +// } + +// // QJniObject window = QNativeInterface::QAndroidApplication::context().callMethod("getWindow", "()Landroid/view/Window;"); +// return window; +// } PlatformHelperAndroid::PlatformHelperAndroid(QObject *parent) : PlatformHelper(parent) { m_instance = this; - QString notificationData = QtAndroid::androidActivity().callObjectMethod("notificationData", "()Ljava/lang/String;").toString(); - if (!notificationData.isNull()) { - notificationActionReceived(notificationData); - } + // QString notificationData = QNativeInterface::QAndroidApplication::context().callMethod("notificationData", "()Ljava/lang/String;").toString(); + // if (!notificationData.isNull()) { + // notificationActionReceived(notificationData); + // } connect(qApp, &QApplication::applicationStateChanged, this, [this](Qt::ApplicationState state){ qCritical() << "----> Application state changed" << state; @@ -92,7 +98,7 @@ void PlatformHelperAndroid::hideSplashScreen() // Android's splash will flicker when fading out twice static bool alreadyHiding = false; if (!alreadyHiding) { - QtAndroid::hideSplashScreen(250); + //QtAndroid::hideSplashScreen(250); alreadyHiding = true; } } @@ -105,23 +111,23 @@ QString PlatformHelperAndroid::machineHostname() const QString PlatformHelperAndroid::deviceSerial() const { - QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;"); + QJniObject activity = QJniObject::callStaticObjectMethod("org/qtproject/qt/android/QtNative", "activity", "()Landroid/app/Activity;"); return activity.callObjectMethod("deviceSerial").toString(); } QString PlatformHelperAndroid::device() const { - return QAndroidJniObject::callStaticObjectMethod("io/guh/nymeaapp/NymeaAppActivity","device").toString(); + return QJniObject::callStaticObjectMethod("io/guh/nymeaapp/NymeaAppActivity", "device").toString(); } QString PlatformHelperAndroid::deviceModel() const { - return QAndroidJniObject::callStaticObjectMethod("io/guh/nymeaapp/NymeaAppActivity","deviceModel").toString(); + return QJniObject::callStaticObjectMethod("io/guh/nymeaapp/NymeaAppActivity", "deviceModel").toString(); } QString PlatformHelperAndroid::deviceManufacturer() const { - return QAndroidJniObject::callStaticObjectMethod("io/guh/nymeaapp/NymeaAppActivity","deviceManufacturer").toString(); + return QJniObject::callStaticObjectMethod("io/guh/nymeaapp/NymeaAppActivity", "deviceManufacturer").toString(); } void PlatformHelperAndroid::vibrate(PlatformHelper::HapticsFeedback feedbackType) @@ -139,7 +145,20 @@ void PlatformHelperAndroid::vibrate(PlatformHelper::HapticsFeedback feedbackType break; } - QtAndroid::androidActivity().callMethod("vibrate","(I)V", duration); + QJniObject context = QNativeInterface::QAndroidApplication::context(); + if (!context.isValid()) { + qDebug() << "Could not get Android context."; + return; + } + + QJniObject vibrator = context.callMethod("getSystemService", "Landroid/content/Context;Ljava/lang/String;", QJniObject::fromString("vibrator").object()); + if (!vibrator.isValid()) { + qDebug() << "Could not get vibrator service."; + return; + } + + // Call the vibrate method + vibrator.callMethod("vibrate", "(J)V", duration); } //void PlatformHelperAndroid::syncThings() @@ -147,7 +166,7 @@ void PlatformHelperAndroid::vibrate(PlatformHelper::HapticsFeedback feedbackType // QAndroidIntent serviceIntent(QtAndroid::androidActivity().object(), // "io/guh/nymeaapp/NymeaAppService"); -// QAndroidJniObject result = QtAndroid::androidActivity().callObjectMethod( +// QJniObject result = QtAndroid::androidActivity().callObjectMethod( // "startService", // "(Landroid/content/Intent;)Landroid/content/ComponentName;", // serviceIntent.handle().object()); @@ -163,7 +182,7 @@ void PlatformHelperAndroid::vibrate(PlatformHelper::HapticsFeedback feedbackType //// m_serviceConnection->handle().callMethod("syncThings", "(Ljava/lang/String;)V", "bla"); -//// QAndroidJniObject result = QtAndroid::androidActivity().callObjectMethod( +//// QJniObject result = QtAndroid::androidActivity().callObjectMethod( //// "syncThings", //// "(Landroid/content/Intent;)Landroid/content/ComponentName;", //// m_serviceConnection->handle().object()); @@ -173,113 +192,120 @@ void PlatformHelperAndroid::setTopPanelColor(const QColor &color) { PlatformHelper::setTopPanelColor(color); - if (QtAndroid::androidSdkVersion() < 21) - return; + // if (QtAndroid::androidSdkVersion() < 21) + // return; - QtAndroid::runOnAndroidThread([=]() { - QAndroidJniObject window = getAndroidWindow(); - window.callMethod("addFlags", "(I)V", FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); - window.callMethod("clearFlags", "(I)V", FLAG_TRANSLUCENT_STATUS); - window.callMethod("setStatusBarColor", "(I)V", color.rgba()); - }); + // QtAndroid::runOnAndroidThread([=]() { + // QJniObject window = getAndroidWindow(); + // window.callMethod("addFlags", "(I)V", FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + // window.callMethod("clearFlags", "(I)V", FLAG_TRANSLUCENT_STATUS); + // window.callMethod("setStatusBarColor", "(I)V", color.rgba()); + // }); - if (((color.red() * 299 + color.green() * 587 + color.blue() * 114) / 1000) > 123) { - setTopPanelTheme(Light); - } else { - setTopPanelTheme(Dark); - } + // if (((color.red() * 299 + color.green() * 587 + color.blue() * 114) / 1000) > 123) { + // setTopPanelTheme(Light); + // } else { + // setTopPanelTheme(Dark); + // } } void PlatformHelperAndroid::setBottomPanelColor(const QColor &color) { PlatformHelper::setBottomPanelColor(color); - if (QtAndroid::androidSdkVersion() < 21) - return; + // if (QtAndroid::androidSdkVersion() < 21) + // return; - QtAndroid::runOnAndroidThread([=]() { - QAndroidJniObject window = getAndroidWindow(); - window.callMethod("clearFlags", "(I)V", FLAG_TRANSLUCENT_NAVIGATION); - window.callMethod("setNavigationBarColor", "(I)V", color.rgba()); + // QtAndroid::runOnAndroidThread([=]() { + // QJniObject window = getAndroidWindow(); + // window.callMethod("clearFlags", "(I)V", FLAG_TRANSLUCENT_NAVIGATION); + // window.callMethod("setNavigationBarColor", "(I)V", color.rgba()); - if (((color.red() * 299 + color.green() * 587 + color.blue() * 114) / 1000) > 123) { - setBottomPanelTheme(Light); - } else { - setBottomPanelTheme(Dark); - } - }); + // if (((color.red() * 299 + color.green() * 587 + color.blue() * 114) / 1000) > 123) { + // setBottomPanelTheme(Light); + // } else { + // setBottomPanelTheme(Dark); + // } + // }); } void PlatformHelperAndroid::setTopPanelTheme(PlatformHelperAndroid::Theme theme) { - if (QtAndroid::androidSdkVersion() < 23) - return; + Q_UNUSED(theme) + // if (QtAndroid::androidSdkVersion() < 23) + // return; - QtAndroid::runOnAndroidThread([=]() { - QAndroidJniObject window = getAndroidWindow(); - QAndroidJniObject view = window.callObjectMethod("getDecorView", "()Landroid/view/View;"); - int visibility = view.callMethod("getSystemUiVisibility", "()I"); - if (theme == Theme::Light) - visibility |= SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; - else - visibility &= ~SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; - view.callMethod("setSystemUiVisibility", "(I)V", visibility); - }); + // QtAndroid::runOnAndroidThread([=]() { + // QJniObject window = getAndroidWindow(); + // QJniObject view = window.callObjectMethod("getDecorView", "()Landroid/view/View;"); + // int visibility = view.callMethod("getSystemUiVisibility", "()I"); + // if (theme == Theme::Light) + // visibility |= SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; + // else + // visibility &= ~SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; + // view.callMethod("setSystemUiVisibility", "(I)V", visibility); + // }); } void PlatformHelperAndroid::setBottomPanelTheme(Theme theme) { - if (QtAndroid::androidSdkVersion() < 23) - return; + Q_UNUSED(theme) - QtAndroid::runOnAndroidThread([=]() { - QAndroidJniObject window = getAndroidWindow(); - QAndroidJniObject view = window.callObjectMethod("getDecorView", "()Landroid/view/View;"); - int visibility = view.callMethod("getSystemUiVisibility", "()I"); - if (theme == Theme::Light) - visibility |= SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; - else - visibility &= ~SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; - view.callMethod("setSystemUiVisibility", "(I)V", visibility); - }); + // if (QtAndroid::androidSdkVersion() < 23) + // return; + + // QtAndroid::runOnAndroidThread([=]() { + // QJniObject window = getAndroidWindow(); + // QJniObject view = window.callObjectMethod("getDecorView", "()Landroid/view/View;"); + // int visibility = view.callMethod("getSystemUiVisibility", "()I"); + // if (theme == Theme::Light) + // visibility |= SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; + // else + // visibility &= ~SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; + // view.callMethod("setSystemUiVisibility", "(I)V", visibility); + // }); } int PlatformHelperAndroid::topPadding() const { // Edge to edge has been forced since android SDK 35 // We don't want to handle it in earlied versions. - if (QtAndroid::androidSdkVersion() < 35) - return 0; + // if (QtAndroid::androidSdkVersion() < 35) + // return 0; - return QtAndroid::androidActivity().callMethod("topPadding") / QApplication::primaryScreen()->devicePixelRatio(); + //return QNativeInterface::QAndroidApplication::context().callMethod("topPadding") / QApplication::primaryScreen()->devicePixelRatio(); + return 0; } int PlatformHelperAndroid::bottomPadding() const { // Edge to edge has been forced since android SDK 35 // We don't want to handle it in earlied versions. - if (QtAndroid::androidSdkVersion() < 35) - return 0; + // if (QtAndroid::androidSdkVersion() < 35) + // return 0; - return QtAndroid::androidActivity().callMethod("bottomPadding") / QApplication::primaryScreen()->devicePixelRatio(); + // return QNativeInterface::QAndroidApplication::context().callMethod("bottomPadding") / QApplication::primaryScreen()->devicePixelRatio(); + return 0; } bool PlatformHelperAndroid::darkModeEnabled() const { - return QtAndroid::androidActivity().callMethod("darkModeEnabled"); + return QNativeInterface::QAndroidApplication::context().callMethod("darkModeEnabled"); } bool PlatformHelperAndroid::locationServicesEnabled() const { - jboolean enabled = QtAndroid::androidActivity().callMethod("locationServicesEnabled", "()Z"); - return enabled; + // jboolean enabled = QNativeInterface::QAndroidApplication::context().callMethod("locationServicesEnabled", "()Z"); + // return enabled; + return true; } void PlatformHelperAndroid::shareFile(const QString &fileName) { - QtAndroid::androidActivity().callMethod("shareFile", "(Ljava/lang/String;)V", - QAndroidJniObject::fromString(fileName).object() - ); + Q_UNUSED(fileName) + // QNativeInterface::QAndroidApplication::context().callMethod("shareFile", "(Ljava/lang/String;)V", + // QJniObject::fromString(fileName).object() + // ); } void PlatformHelperAndroid::darkModeEnabledChangedJNI() diff --git a/nymea-app/platformintegration/android/platformhelperandroid.h b/nymea-app/platformintegration/android/platformhelperandroid.h index ed88f782..3edbaeda 100644 --- a/nymea-app/platformintegration/android/platformhelperandroid.h +++ b/nymea-app/platformintegration/android/platformhelperandroid.h @@ -28,8 +28,9 @@ #include "platformhelper.h" #include -#include -#include +#include +#include +#include class PlatformHelperAndroid : public PlatformHelper { @@ -67,8 +68,6 @@ public: static void notificationActionReceivedJNI(JNIEnv *env, jobject /*thiz*/, jstring data); static void locationServicesEnabledChangedJNI(); -private: - static void permissionRequestFinished(const QtAndroid::PermissionResultMap &); }; #endif // PLATFORMHELPERANDROID_H diff --git a/nymea-app/platformintegration/android/platformpermissionsandroid.cpp b/nymea-app/platformintegration/android/platformpermissionsandroid.cpp index df75200f..213942a1 100644 --- a/nymea-app/platformintegration/android/platformpermissionsandroid.cpp +++ b/nymea-app/platformintegration/android/platformpermissionsandroid.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include "logging.h" @@ -53,94 +53,227 @@ PlatformPermissionsAndroid::PlatformPermissionsAndroid(QObject *parent) } -void PlatformPermissionsAndroid::requestPermission(PlatformPermissions::Permission permission) -{ - if (permissionMap().contains(permission)) { - qCDebug(dcPlatformPermissions()) << "Requesting permissions:" << permissionMap().value(permission); - QtAndroid::requestPermissions({permissionMap().value(permission)}, &permissionResultCallback); - } -} - -void PlatformPermissionsAndroid::openPermissionSettings() -{ - qCDebug(dcPlatformPermissions()) << "Opening permission dialog."; - QAndroidJniObject packageName = QtAndroid::androidContext().callObjectMethod("getPackageName", "()Ljava/lang/String;"); - QString packageUri = "package:" + packageName.toString(); - QAndroidJniObject uri = QAndroidJniObject::callStaticObjectMethod("android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", QAndroidJniObject::fromString(packageUri).object()); - QAndroidIntent intent = QAndroidIntent("android.settings.APPLICATION_DETAILS_SETTINGS"); - intent.handle().callObjectMethod("setData", "(Landroid/net/Uri;)Landroid/content/Intent;", uri.object()); - intent.handle().callObjectMethod("addFlags", "(I)Landroid/content/Intent;", FLAG_ACTIVITY_NEW_TASK); - QtAndroid::androidContext().callMethod("startActivity", "(Landroid/content/Intent;)V", intent.handle().object()); -} - -QHash PlatformPermissionsAndroid::permissionMap() const -{ - QOperatingSystemVersion osVersion = QOperatingSystemVersion::current(); - if (osVersion.majorVersion() <= 9) { - return { - {PlatformPermissions::PermissionBluetooth, {"android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}}, - {PlatformPermissions::PermissionLocation, {"android.permission.ACCESS_FINE_LOCATION"}}, - {PlatformPermissions::PermissionBackgroundLocation, {"android.permission.ACCESS_FINE_LOCATION"}} - }; - } - if (osVersion.majorVersion() <= 10) { - return { - {PlatformPermissions::PermissionBluetooth, {"android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}}, - {PlatformPermissions::PermissionLocation, {"android.permission.ACCESS_FINE_LOCATION"}}, - {PlatformPermissions::PermissionBackgroundLocation, {"android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_BACKGROUND_LOCATION"}} - }; - } - if (osVersion.majorVersion() <= 12) { - return { - // TODO: Once QtBluetooth does not request the COARSE_LOCATION and FINE_LOCATION for Bluetooth any more, remove it from here. The new Bluetooth permissions would be enough. - {PlatformPermissions::PermissionBluetooth, {"android.permission.BLUETOOTH_SCAN", "android.permission.BLUETOOTH_CONNECT", "android.permission.BLUETOOTH_ADVERTISE", "android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}}, - {PlatformPermissions::PermissionLocation, {"android.permission.ACCESS_FINE_LOCATION"}}, - {PlatformPermissions::PermissionBackgroundLocation, {"android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_BACKGROUND_LOCATION"}} - }; - } - return { - // TODO: Once QtBluetooth does not request the COARSE_LOCATION and FINE_LOCATION for Bluetooth any more, remove it from here. The new Bluetooth permissions would be enough. - {PlatformPermissions::PermissionBluetooth, {"android.permission.BLUETOOTH_SCAN", "android.permission.BLUETOOTH_CONNECT", "android.permission.BLUETOOTH_ADVERTISE", "android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}}, - {PlatformPermissions::PermissionLocation, {"android.permission.ACCESS_FINE_LOCATION"}}, - {PlatformPermissions::PermissionBackgroundLocation, {"android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_BACKGROUND_LOCATION"}}, - {PlatformPermissions::PermissionNotifications, {"android.permission.POST_NOTIFICATIONS"}} - }; -} - -PlatformPermissions::PermissionStatus PlatformPermissionsAndroid::checkPermission(Permission permission) const +PlatformPermissions::PermissionStatus PlatformPermissionsAndroid::checkPermission(Permission platformPermission) const { PermissionStatus status = PermissionStatusGranted; - QStringList androidPermissions = permissionMap().value(permission); - qCDebug(dcPlatformPermissions()) << "Checking permission" << permission << "(" << androidPermissions << ")"; - foreach (const QString androidPermission, androidPermissions) { - if (QtAndroid::shouldShowRequestPermissionRationale(androidPermission) || m_requestedButDeniedPermissions.contains(androidPermission)) { - qCDebug(dcPlatformPermissions()) << "Permission:" << androidPermission << "denied"; - status = PermissionStatusDenied; + qCDebug(dcPlatformPermissions()) << "Checking permission" << platformPermission; + + switch (platformPermission) { + case PlatformPermissions::PermissionBluetooth: { + QBluetoothPermission permission; + + // Status prüfen + auto status = qApp->checkPermission(permission); + + switch (status) { + case Qt::PermissionStatus::Granted: + qCDebug(dcPlatformPermissions()) << "Bluetooth permission already granted."; + break; + case Qt::PermissionStatus::Denied: + qCDebug(dcPlatformPermissions()) << "Bluetooth permission denied."; + break; + case Qt::PermissionStatus::Undetermined: + qCDebug(dcPlatformPermissions()) << "Bluetooth permission not yet requested. Requesting..."; + qApp->requestPermission(permission, [](const QPermission &perm){ + if (perm.status() == Qt::PermissionStatus::Granted) + qCDebug(dcPlatformPermissions()) << "Bluetooth permission granted after request."; + else + qCDebug(dcPlatformPermissions()) << "Bluetooth permission denied after request."; + }); + break; } - if (QtAndroid::checkPermission(androidPermission) == QtAndroid::PermissionResult::Denied) { - qDebug(dcPlatformPermissions()) << "Permission:" << androidPermission << "not determined"; - if (status != PermissionStatusDenied) { - status = PermissionStatusNotDetermined; - } - } else { - qDebug(dcPlatformPermissions()) << "Permission:" << androidPermission << "granted"; + break; + } + case PlatformPermissions::PermissionLocalNetwork: { + QLocationPermission permission; + permission.setAccuracy(QLocationPermission::Precise); + + // Status prüfen + auto status = qApp->checkPermission(permission); + + switch (status) { + case Qt::PermissionStatus::Granted: + qCDebug(dcPlatformPermissions()) << "Location permission already granted."; + break; + case Qt::PermissionStatus::Denied: + qCDebug(dcPlatformPermissions()) << "Location permission denied."; + break; + case Qt::PermissionStatus::Undetermined: + qCDebug(dcPlatformPermissions()) << "Location permission not yet requested. Requesting..."; + qApp->requestPermission(permission, [](const QPermission &perm){ + if (perm.status() == Qt::PermissionStatus::Granted) + qCDebug(dcPlatformPermissions()) << "Location permission granted after request."; + else + qCDebug(dcPlatformPermissions()) << "Location permission denied after request."; + }); + break; } } - qCDebug(dcPlatformPermissions()) << "Permission status for:" << permission << ":" << status; + case PlatformPermissions::PermissionNotifications: { + break; + } + default: + qCWarning(dcPlatformPermissions()) << "Requested status of platform permission" << platformPermission << "but is not implemented yet."; + break; + } return status; } -void PlatformPermissionsAndroid::permissionResultCallback(const QtAndroid::PermissionResultMap &results) +void PlatformPermissionsAndroid::requestPermission(PlatformPermissions::Permission platformPermission) { - foreach (const QString &androidPermission, results.keys()) { - qCDebug(dcPlatformPermissions()) << "Permission result callback:" << androidPermission << (results.value(androidPermission) == QtAndroid::PermissionResult::Granted ? "Granted" : "Denied"); - if (results.value(androidPermission) == QtAndroid::PermissionResult::Denied) { - s_instance->m_requestedButDeniedPermissions.append(androidPermission); - } + switch (platformPermission) { + case PlatformPermissions::PermissionBluetooth: + qCDebug(dcPlatformPermissions()) << "Requesting bluetooth permission"; + qApp->requestPermission(QLocationPermission{}, [platformPermission](const QPermission &permission) { + if (permission.status() == Qt::PermissionStatus::Denied) { + qCWarning(dcPlatformPermissions()) << "Bluetooth permission denied."; + s_instance->m_requestedButDeniedPermissions.append(platformPermission); + } + + if (permission.status() == Qt::PermissionStatus::Granted) + qCDebug(dcPlatformPermissions()) << "Bluetooth permission granted."; + + emit s_instance->bluetoothPermissionChanged(); + }); + break; + case PlatformPermissions::PermissionLocation: { + QLocationPermission locationPermission; + locationPermission.setAccuracy(QLocationPermission::Precise); + qApp->requestPermission(locationPermission, [platformPermission](const QPermission &permission) { + if (permission.status() == Qt::PermissionStatus::Denied) { + qCWarning(dcPlatformPermissions()) << "Location permission denied."; + s_instance->m_requestedButDeniedPermissions.append(platformPermission); + } + + if (permission.status() == Qt::PermissionStatus::Granted) + qCDebug(dcPlatformPermissions()) << "Location permission granted."; + + emit s_instance->locationPermissionChanged(); + }); + break; } - emit s_instance->bluetoothPermissionChanged(); + case PlatformPermissions::PermissionLocalNetwork: { + QFuture permission_request = QtAndroidPrivate::requestPermission("android.permission.POST_NOTIFICATIONS"); + switch(permission_request.result()) + { + case QtAndroidPrivate::Undetermined: + qWarning() << "Permission for posting notifications undetermined!"; + break; + case QtAndroidPrivate::Authorized: + qDebug() << "Permission for posting notifications authorized"; + break; + case QtAndroidPrivate::Denied: + qWarning() << "Permission for posting notifications denied!"; + break; + } + + break; + } + default: + qCWarning(dcPlatformPermissions()) << "Requested platform permission" << platformPermission << "but is not implemented yet."; + break; + } + emit s_instance->locationPermissionChanged(); emit s_instance->backgroundLocationPermissionChanged(); emit s_instance->notificationsPermissionChanged(); + + // if (permissionMap().contains(permission)) { + // qCDebug(dcPlatformPermissions()) << "Requesting permissions:" << permissionMap().value(permission); + + + + // qApp->requestPermission(QCameraPermission{}, [](const QPermission &permission) { + + + // if (permission.status() == Qt::PermissionStatus::Granted) + // takePhoto(); + // }); + + // // QtAndroid::requestPermissions({permissionMap().value(permission)}, &permissionResultCallback); + // } } +// void PlatformPermissionsAndroid::openPermissionSettings() +// { +// qCDebug(dcPlatformPermissions()) << "Opening permission dialog."; +// QJniObject packageName = QtAndroid::androidContext().callObjectMethod("getPackageName", "()Ljava/lang/String;"); +// QString packageUri = "package:" + packageName.toString(); +// QJniObject uri = QJniObject::callStaticObjectMethod("android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", QJniObject::fromString(packageUri).object()); +// QAndroidIntent intent = QAndroidIntent("android.settings.APPLICATION_DETAILS_SETTINGS"); +// intent.handle().callObjectMethod("setData", "(Landroid/net/Uri;)Landroid/content/Intent;", uri.object()); +// intent.handle().callObjectMethod("addFlags", "(I)Landroid/content/Intent;", FLAG_ACTIVITY_NEW_TASK); +// QtAndroid::androidContext().callMethod("startActivity", "(Landroid/content/Intent;)V", intent.handle().object()); +// } + +// QHash PlatformPermissionsAndroid::permissionMap() const +// { +// QOperatingSystemVersion osVersion = QOperatingSystemVersion::current(); +// if (osVersion.majorVersion() <= 9) { +// return { +// {PlatformPermissions::PermissionBluetooth, {"android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}}, +// {PlatformPermissions::PermissionLocation, {"android.permission.ACCESS_FINE_LOCATION"}}, +// {PlatformPermissions::PermissionBackgroundLocation, {"android.permission.ACCESS_FINE_LOCATION"}} +// }; +// } +// if (osVersion.majorVersion() <= 10) { +// return { +// {PlatformPermissions::PermissionBluetooth, {"android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}}, +// {PlatformPermissions::PermissionLocation, {"android.permission.ACCESS_FINE_LOCATION"}}, +// {PlatformPermissions::PermissionBackgroundLocation, {"android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_BACKGROUND_LOCATION"}} +// }; +// } +// if (osVersion.majorVersion() <= 12) { +// return { +// // TODO: Once QtBluetooth does not request the COARSE_LOCATION and FINE_LOCATION for Bluetooth any more, remove it from here. The new Bluetooth permissions would be enough. +// {PlatformPermissions::PermissionBluetooth, {"android.permission.BLUETOOTH_SCAN", "android.permission.BLUETOOTH_CONNECT", "android.permission.BLUETOOTH_ADVERTISE", "android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}}, +// {PlatformPermissions::PermissionLocation, {"android.permission.ACCESS_FINE_LOCATION"}}, +// {PlatformPermissions::PermissionBackgroundLocation, {"android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_BACKGROUND_LOCATION"}} +// }; +// } +// return { +// // TODO: Once QtBluetooth does not request the COARSE_LOCATION and FINE_LOCATION for Bluetooth any more, remove it from here. The new Bluetooth permissions would be enough. +// {PlatformPermissions::PermissionBluetooth, {"android.permission.BLUETOOTH_SCAN", "android.permission.BLUETOOTH_CONNECT", "android.permission.BLUETOOTH_ADVERTISE", "android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}}, +// {PlatformPermissions::PermissionLocation, {"android.permission.ACCESS_FINE_LOCATION"}}, +// {PlatformPermissions::PermissionBackgroundLocation, {"android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_BACKGROUND_LOCATION"}}, +// {PlatformPermissions::PermissionNotifications, {"android.permission.POST_NOTIFICATIONS"}} +// }; +// } + +// PlatformPermissions::PermissionStatus PlatformPermissionsAndroid::checkPermission(Permission permission) const +// { +// PermissionStatus status = PermissionStatusGranted; +// QStringList androidPermissions = permissionMap().value(permission); +// qCDebug(dcPlatformPermissions()) << "Checking permission" << permission << "(" << androidPermissions << ")"; +// foreach (const QString androidPermission, androidPermissions) { +// if (QtAndroid::shouldShowRequestPermissionRationale(androidPermission) || m_requestedButDeniedPermissions.contains(androidPermission)) { +// qCDebug(dcPlatformPermissions()) << "Permission:" << androidPermission << "denied"; +// status = PermissionStatusDenied; +// } +// if (QtAndroid::checkPermission(androidPermission) == QtAndroid::PermissionResult::Denied) { +// qDebug(dcPlatformPermissions()) << "Permission:" << androidPermission << "not determined"; +// if (status != PermissionStatusDenied) { +// status = PermissionStatusNotDetermined; +// } +// } else { +// qDebug(dcPlatformPermissions()) << "Permission:" << androidPermission << "granted"; +// } +// } +// qCDebug(dcPlatformPermissions()) << "Permission status for:" << permission << ":" << status; +// return status; +// } + +// void PlatformPermissionsAndroid::permissionResultCallback(const QtAndroid::PermissionResultMap &results) +// { +// foreach (const QString &androidPermission, results.keys()) { +// qCDebug(dcPlatformPermissions()) << "Permission result callback:" << androidPermission << (results.value(androidPermission) == QtAndroid::PermissionResult::Granted ? "Granted" : "Denied"); +// if (results.value(androidPermission) == QtAndroid::PermissionResult::Denied) { +// s_instance->m_requestedButDeniedPermissions.append(androidPermission); +// } +// } +// emit s_instance->bluetoothPermissionChanged(); +// emit s_instance->locationPermissionChanged(); +// emit s_instance->backgroundLocationPermissionChanged(); +// emit s_instance->notificationsPermissionChanged(); +// } + diff --git a/nymea-app/platformintegration/android/platformpermissionsandroid.h b/nymea-app/platformintegration/android/platformpermissionsandroid.h index 0a43d40a..6f5ea583 100644 --- a/nymea-app/platformintegration/android/platformpermissionsandroid.h +++ b/nymea-app/platformintegration/android/platformpermissionsandroid.h @@ -26,8 +26,7 @@ #define PLATFORMPERMISSIONSANDROID_H #include "../platformpermissions.h" - -#include +#include class PlatformPermissionsAndroid : public PlatformPermissions { @@ -35,20 +34,14 @@ class PlatformPermissionsAndroid : public PlatformPermissions public: explicit PlatformPermissionsAndroid(QObject *parent = nullptr); - PermissionStatus checkPermission(Permission permission) const override; - - void requestPermission(Permission permission) override; - void openPermissionSettings() override; - -signals: + PermissionStatus checkPermission(Permission platformPermission) const override; + void requestPermission(Permission platformPermission) override; private: - QHash permissionMap() const; - - QStringList m_requestedButDeniedPermissions; - static PlatformPermissionsAndroid *s_instance; - static void permissionResultCallback(const QtAndroid::PermissionResultMap &results); + + QList m_requestedButDeniedPermissions; + QList m_grantedPermission; }; diff --git a/nymea-app/pushnotifications.cpp b/nymea-app/pushnotifications.cpp index 0b2266ef..3e5ca749 100644 --- a/nymea-app/pushnotifications.cpp +++ b/nymea-app/pushnotifications.cpp @@ -26,11 +26,16 @@ #include "platformhelper.h" #include +#include #if defined Q_OS_ANDROID -#include -#include -#include +#include +#include + +#include // QJniEnvironment +#include // QJniObject +#include // QtJniTypes::Context / Activity +#include static PushNotifications *m_client_pointer; #endif @@ -82,14 +87,50 @@ void PushNotifications::registerForPush() { #if defined Q_OS_ANDROID && defined WITH_FIREBASE qDebug() << "Checking for play services"; - jboolean playServicesAvailable = QAndroidJniObject::callStaticMethod("io.guh.nymeaapp.NymeaAppNotificationService", "checkPlayServices", "()Z"); + jboolean playServicesAvailable = QJniObject::callStaticMethod("io.guh.nymeaapp.NymeaAppNotificationService", "checkPlayServices", "()Z"); if (playServicesAvailable) { + qDebug() << "Setting up firebase"; m_client_pointer = this; - m_firebaseApp = ::firebase::App::Create(::firebase::AppOptions(), QAndroidJniEnvironment(), QtAndroid::androidActivity().object()); - m_firebase_initializer.Initialize(m_firebaseApp, nullptr, [](::firebase::App * fapp, void *) { - return ::firebase::messaging::Initialize( *fapp, (::firebase::messaging::Listener *)m_client_pointer); - }); + + JNIEnv *jni = QJniEnvironment().jniEnv(); + QtJniTypes::Context ctx = QNativeInterface::QAndroidApplication::context(); + jobject contextObj = ctx.object(); + + m_firebaseApp = firebase::App::Create(firebase::AppOptions(), jni, contextObj); + + firebase::messaging::Initialize(*m_firebaseApp, this); + firebase::messaging::SetListener(this); + + // (Optional, Android 13+): Benachrichtigungs-Erlaubnis anfragen + // firebase::messaging::RequestPermission(); + + + + // // Activity + JNIEnv besorgen + // JNIEnv* env = QNativeInterface::QAndroidApplication::jniEnv(); + // jobject activity = QNativeInterface::QAndroidApplication::context(); + + // // Firebase App erstellen + // m_firebaseApp = firebase::App::Create(firebase::AppOptions(), env, activity); + + // // Messaging initialisieren und Listener setzen + // auto initResult = firebase::messaging::Initialize(*m_firebaseApp); + // if (initResult != firebase::kFutureStatusComplete) { + // // optional: warten oder loggen + // } + // firebase::messaging::SetListener(this); + + // // Optional: Token anfordern (wird i.d.R. via OnTokenReceived geliefert) + // firebase::messaging::RequestPermission(); // Android 13+ für Notifications sinnvoll + + + + + // m_firebaseApp = ::firebase::App::Create(::firebase::AppOptions(), QAndroidJniEnvironment(), QtAndroid::androidActivity().object()); + // m_firebase_initializer.Initialize(m_firebaseApp, nullptr, [](::firebase::App * fapp, void *) { + // return ::firebase::messaging::Initialize( *fapp, (::firebase::messaging::Listener *)m_client_pointer); + // }); } else { qDebug() << "Google Play Services not available. Cannot connect to push client."; } diff --git a/nymea-app/resources.qrc b/nymea-app/resources.qrc index 5030b43d..4a7c56a7 100644 --- a/nymea-app/resources.qrc +++ b/nymea-app/resources.qrc @@ -323,5 +323,7 @@ ui/components/BackgroundFocusHandler.qml ui/components/LicenseInformationItem.qml ui/shaders/coloricon.frag.qsb + ui/shaders/brightnesscircle.frag.qsb + ui/shaders/colorizedimage.frag.qsb diff --git a/nymea-app/styles.qrc b/nymea-app/styles.qrc index 4fa9cbde..cc23c2a0 100644 --- a/nymea-app/styles.qrc +++ b/nymea-app/styles.qrc @@ -45,5 +45,6 @@ styles/lime/Background.qml styles/mellow/Background.qml styles/noir/Background.qml + styles/dark/ItemDelegate.qml diff --git a/nymea-app/styles/dark/Background.qml b/nymea-app/styles/dark/Background.qml index 9a4e71a5..10ca63bd 100644 --- a/nymea-app/styles/dark/Background.qml +++ b/nymea-app/styles/dark/Background.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import Nymea 1.0 +import QtQuick +import Nymea Rectangle { color: Style.backgroundColor diff --git a/nymea-app/styles/dark/Button.qml b/nymea-app/styles/dark/Button.qml index f34fb1e8..e97fb06e 100644 --- a/nymea-app/styles/dark/Button.qml +++ b/nymea-app/styles/dark/Button.qml @@ -2,6 +2,7 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Copyright (C) 2017 The Qt Company Ltd. * Copyright (C) 2013 - 2024, nymea GmbH * Copyright (C) 2024 - 2025, chargebyte austria GmbH * @@ -22,90 +23,78 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Templates 2.2 as T -import QtQuick.Controls 2.2 -import QtQuick.Controls.impl 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Controls.Material.impl 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl T.Button { id: control - implicitWidth: Math.max(background ? background.implicitWidth : 0, - contentItem.implicitWidth + leftPadding + rightPadding) - implicitHeight: Math.max(background ? background.implicitHeight : 0, - contentItem.implicitHeight + topPadding + bottomPadding) - baselineOffset: contentItem.y + contentItem.baselineOffset + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) - // external vertical padding is 6 (to increase touch area) - padding: 12 - leftPadding: padding - 4 - rightPadding: padding - 4 + topInset: 6 + bottomInset: 6 + verticalPadding: Material.buttonVerticalPadding + leftPadding: Material.buttonLeftPadding(flat, hasIcon && (display !== AbstractButton.TextOnly)) + rightPadding: Material.buttonRightPadding(flat, hasIcon && (display !== AbstractButton.TextOnly), + (text !== "") && (display !== AbstractButton.IconOnly)) + spacing: 8 - Material.elevation: flat ? control.down || control.hovered ? 2 : 0 - : control.down ? 8 : 2 - Material.background: flat ? "transparent" : undefined + icon.width: 24 + icon.height: 24 + icon.color: !enabled ? Material.hintTextColor : + (control.flat && control.highlighted) || (control.checked && !control.highlighted) ? Material.accentColor : + highlighted ? Material.primaryHighlightedTextColor : Material.foreground - contentItem: Text { + readonly property bool hasIcon: icon.name.length > 0 || icon.source.toString().length > 0 + + Material.elevation: control.down ? 8 : 2 + Material.roundedScale: Material.FullScale + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon text: control.text - color: Style.foregroundColor - font.bold: control.font.bold - font.capitalization: Font.AllUppercase - font.family: control.font.family - font.hintingPreference: control.font.hintingPreference - font.italic: control.font.italic - font.letterSpacing: 2 - font.overline: control.font.overline - font.pixelSize: app.smallFont - font.weight: Font.Bold - - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - elide: Text.ElideRight + font: control.font + color: !control.enabled ? control.Material.hintTextColor : + (control.flat && control.highlighted) || (control.checked && !control.highlighted) ? control.Material.accentColor : + control.highlighted ? control.Material.primaryHighlightedTextColor : control.Material.foreground } - // TODO: Add a proper ripple/ink effect for mouse/touch input and focus state background: Rectangle { implicitWidth: 64 - implicitHeight: Style.smallDelegateHeight + implicitHeight: control.Material.buttonHeight - // external vertical padding is 6 (to increase touch area) - y: 6 - width: parent.width - height: parent.height - 12 - radius: Style.smallCornerRadius - color: !control.enabled ? control.Material.buttonDisabledColor : - control.highlighted ? control.Material.highlightedButtonColor : control.Material.accentColor - - PaddedRectangle { - y: parent.height - 4 - width: parent.width - height: 4 - radius: 2 - topPadding: -2 - clip: true - visible: control.checkable && (!control.highlighted || control.flat) - color: control.checked && control.enabled ? control.Material.accentColor : control.Material.secondaryTextColor - } + radius: control.Material.roundedScale === Material.FullScale ? height / 2 : control.Material.roundedScale + color: control.Material.buttonColor(control.Material.theme, control.Material.background, + control.Material.accent, control.enabled, control.flat, control.highlighted, control.checked) // The layer is disabled when the button color is transparent so you can do // Material.background: "transparent" and get a proper flat button without needing // to set Material.elevation as well - layer.enabled: control.enabled && control.Material.buttonColor.a > 0 - layer.effect: ElevationEffect { + layer.enabled: control.enabled && color.a > 0 && !control.flat + layer.effect: RoundedElevationEffect { elevation: control.Material.elevation + roundedScale: control.background.radius } Ripple { - clipRadius: 2 + clip: true + clipRadius: parent.radius width: parent.width height: parent.height pressed: control.pressed anchor: control - active: control.down || control.visualFocus || control.hovered - color: control.Material.rippleColor + active: enabled && (control.down || control.visualFocus || control.hovered) + color: control.flat && control.highlighted ? control.Material.highlightedRippleColor : control.Material.rippleColor } } } diff --git a/nymea-app/styles/dark/Dialog.qml b/nymea-app/styles/dark/Dialog.qml index 98e5fdd0..28cc4d5d 100644 --- a/nymea-app/styles/dark/Dialog.qml +++ b/nymea-app/styles/dark/Dialog.qml @@ -3,6 +3,8 @@ /**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2013 - 2024, nymea GmbH +** Copyright (C) 2024 - 2025, chargebyte austria GmbH ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. @@ -36,34 +38,13 @@ ** ****************************************************************************/ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright (C) 2013 - 2024, nymea GmbH -* Copyright (C) 2024 - 2025, chargebyte austria GmbH -* -* This file is part of nymea-app. -* -* nymea-app is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* nymea-app is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with nymea-app. If not, see . -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl -import QtQuick 2.9 -import QtQuick.Templates 2.2 as T -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Controls.Material.impl 2.2 -import Nymea 1.0 +import Nymea T.Dialog { id: control diff --git a/nymea-app/styles/dark/ItemDelegate.qml b/nymea-app/styles/dark/ItemDelegate.qml new file mode 100644 index 00000000..ae45332d --- /dev/null +++ b/nymea-app/styles/dark/ItemDelegate.qml @@ -0,0 +1,57 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +import Nymea + +T.ItemDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 16 + verticalPadding: 8 + spacing: 16 + + icon.width: 24 + icon.height: 24 + icon.color: enabled ? Material.foreground : Material.hintTextColor + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.enabled ? control.Material.foreground : control.Material.hintTextColor + } + + background: Rectangle { + implicitHeight: control.Material.delegateHeight + color: control.highlighted ? control.Material.listHighlightColor : "transparent" + radius: Style.cornerRadius + + Ripple { + width: parent.width + height: parent.height + + clip: true + pressed: control.pressed + anchor: control + active: enabled && (control.down || control.visualFocus || control.hovered) + color: control.Material.rippleColor + } + } +} diff --git a/nymea-app/styles/dark/Page.qml b/nymea-app/styles/dark/Page.qml index e9ad1436..e763136e 100644 --- a/nymea-app/styles/dark/Page.qml +++ b/nymea-app/styles/dark/Page.qml @@ -22,9 +22,9 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import QtQuick.Templates 2.2 -import QtQuick.Controls.Material 2.2 +import QtQuick +import QtQuick.Templates +import QtQuick.Controls.Material Page { background: Background {} diff --git a/nymea-app/styles/dark/Style.qml b/nymea-app/styles/dark/Style.qml index 4c500004..0b83254c 100644 --- a/nymea-app/styles/dark/Style.qml +++ b/nymea-app/styles/dark/Style.qml @@ -23,7 +23,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ pragma Singleton -import QtQuick 2.0 +import QtQuick import "../../ui" StyleBase { diff --git a/nymea-app/styles/energize/Background.qml b/nymea-app/styles/energize/Background.qml index 8ecace77..ca6c179c 100644 --- a/nymea-app/styles/energize/Background.qml +++ b/nymea-app/styles/energize/Background.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import Nymea 1.0 +import QtQuick +import Nymea Rectangle { gradient: Gradient { diff --git a/nymea-app/styles/energize/Button.qml b/nymea-app/styles/energize/Button.qml index fa205f8f..5d63db16 100644 --- a/nymea-app/styles/energize/Button.qml +++ b/nymea-app/styles/energize/Button.qml @@ -22,13 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 +import QtQuick import QtQuick.Templates 2.2 as T -import QtQuick.Controls 2.2 +import QtQuick.Controls import QtQuick.Controls.impl 2.2 -import QtQuick.Controls.Material 2.2 +import QtQuick.Controls.Material import QtQuick.Controls.Material.impl 2.2 -import Nymea 1.0 +import Nymea T.Button { id: control diff --git a/nymea-app/styles/energize/Page.qml b/nymea-app/styles/energize/Page.qml index e9ad1436..a27db034 100644 --- a/nymea-app/styles/energize/Page.qml +++ b/nymea-app/styles/energize/Page.qml @@ -22,9 +22,9 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 +import QtQuick import QtQuick.Templates 2.2 -import QtQuick.Controls.Material 2.2 +import QtQuick.Controls.Material Page { background: Background {} diff --git a/nymea-app/styles/energize/Style.qml b/nymea-app/styles/energize/Style.qml index 071fa83f..8984d331 100644 --- a/nymea-app/styles/energize/Style.qml +++ b/nymea-app/styles/energize/Style.qml @@ -23,7 +23,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ pragma Singleton -import QtQuick 2.0 +import QtQuick import "../../ui" StyleBase { diff --git a/nymea-app/styles/light/Background.qml b/nymea-app/styles/light/Background.qml index 9ee708bc..935bafd8 100644 --- a/nymea-app/styles/light/Background.qml +++ b/nymea-app/styles/light/Background.qml @@ -22,8 +22,9 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import Nymea 1.0 +import QtQuick +import Nymea + import "qrc:/styles/light" Rectangle { diff --git a/nymea-app/styles/light/Button.qml b/nymea-app/styles/light/Button.qml index 347a3fee..ce03673b 100644 --- a/nymea-app/styles/light/Button.qml +++ b/nymea-app/styles/light/Button.qml @@ -22,13 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 +import QtQuick import QtQuick.Templates 2.2 as T -import QtQuick.Controls 2.2 +import QtQuick.Controls import QtQuick.Controls.impl 2.2 -import QtQuick.Controls.Material 2.2 +import QtQuick.Controls.Material import QtQuick.Controls.Material.impl 2.2 -import Nymea 1.0 +import Nymea T.Button { id: control diff --git a/nymea-app/styles/light/Dialog.qml b/nymea-app/styles/light/Dialog.qml index 98e5fdd0..ff61c50e 100644 --- a/nymea-app/styles/light/Dialog.qml +++ b/nymea-app/styles/light/Dialog.qml @@ -3,6 +3,8 @@ /**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2013 - 2024, nymea GmbH +** Copyright (C) 2024 - 2025, chargebyte austria GmbH ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. @@ -36,34 +38,12 @@ ** ****************************************************************************/ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright (C) 2013 - 2024, nymea GmbH -* Copyright (C) 2024 - 2025, chargebyte austria GmbH -* -* This file is part of nymea-app. -* -* nymea-app is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* nymea-app is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with nymea-app. If not, see . -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -import QtQuick 2.9 -import QtQuick.Templates 2.2 as T -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Controls.Material.impl 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl +import Nymea T.Dialog { id: control diff --git a/nymea-app/styles/light/Page.qml b/nymea-app/styles/light/Page.qml index e9ad1436..a27db034 100644 --- a/nymea-app/styles/light/Page.qml +++ b/nymea-app/styles/light/Page.qml @@ -22,9 +22,9 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 +import QtQuick import QtQuick.Templates 2.2 -import QtQuick.Controls.Material 2.2 +import QtQuick.Controls.Material Page { background: Background {} diff --git a/nymea-app/styles/light/Style.qml b/nymea-app/styles/light/Style.qml index 56c336c6..8b049a15 100644 --- a/nymea-app/styles/light/Style.qml +++ b/nymea-app/styles/light/Style.qml @@ -23,7 +23,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ pragma Singleton -import QtQuick 2.0 +import QtQuick import "../../ui" StyleBase { diff --git a/nymea-app/styles/lime/Background.qml b/nymea-app/styles/lime/Background.qml index 9a4e71a5..10ca63bd 100644 --- a/nymea-app/styles/lime/Background.qml +++ b/nymea-app/styles/lime/Background.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import Nymea 1.0 +import QtQuick +import Nymea Rectangle { color: Style.backgroundColor diff --git a/nymea-app/styles/lime/Button.qml b/nymea-app/styles/lime/Button.qml index 0023b6e5..53fafe8f 100644 --- a/nymea-app/styles/lime/Button.qml +++ b/nymea-app/styles/lime/Button.qml @@ -22,11 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 +import QtQuick import QtQuick.Templates 2.2 as T -import QtQuick.Controls 2.2 +import QtQuick.Controls import QtQuick.Controls.impl 2.2 -import QtQuick.Controls.Material 2.2 +import QtQuick.Controls.Material import QtQuick.Controls.Material.impl 2.2 T.Button { diff --git a/nymea-app/styles/lime/Page.qml b/nymea-app/styles/lime/Page.qml index e9ad1436..a27db034 100644 --- a/nymea-app/styles/lime/Page.qml +++ b/nymea-app/styles/lime/Page.qml @@ -22,9 +22,9 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 +import QtQuick import QtQuick.Templates 2.2 -import QtQuick.Controls.Material 2.2 +import QtQuick.Controls.Material Page { background: Background {} diff --git a/nymea-app/styles/lime/Style.qml b/nymea-app/styles/lime/Style.qml index 85b15927..58ec21ae 100644 --- a/nymea-app/styles/lime/Style.qml +++ b/nymea-app/styles/lime/Style.qml @@ -23,7 +23,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ pragma Singleton -import QtQuick 2.0 +import QtQuick import "../../ui" StyleBase { diff --git a/nymea-app/styles/mellow/Background.qml b/nymea-app/styles/mellow/Background.qml index 9a4e71a5..10ca63bd 100644 --- a/nymea-app/styles/mellow/Background.qml +++ b/nymea-app/styles/mellow/Background.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import Nymea 1.0 +import QtQuick +import Nymea Rectangle { color: Style.backgroundColor diff --git a/nymea-app/styles/mellow/Button.qml b/nymea-app/styles/mellow/Button.qml index 347a3fee..ce03673b 100644 --- a/nymea-app/styles/mellow/Button.qml +++ b/nymea-app/styles/mellow/Button.qml @@ -22,13 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 +import QtQuick import QtQuick.Templates 2.2 as T -import QtQuick.Controls 2.2 +import QtQuick.Controls import QtQuick.Controls.impl 2.2 -import QtQuick.Controls.Material 2.2 +import QtQuick.Controls.Material import QtQuick.Controls.Material.impl 2.2 -import Nymea 1.0 +import Nymea T.Button { id: control diff --git a/nymea-app/styles/mellow/Page.qml b/nymea-app/styles/mellow/Page.qml index e9ad1436..a27db034 100644 --- a/nymea-app/styles/mellow/Page.qml +++ b/nymea-app/styles/mellow/Page.qml @@ -22,9 +22,9 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 +import QtQuick import QtQuick.Templates 2.2 -import QtQuick.Controls.Material 2.2 +import QtQuick.Controls.Material Page { background: Background {} diff --git a/nymea-app/styles/mellow/Style.qml b/nymea-app/styles/mellow/Style.qml index b3ca2e30..a3ab2595 100644 --- a/nymea-app/styles/mellow/Style.qml +++ b/nymea-app/styles/mellow/Style.qml @@ -23,7 +23,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ pragma Singleton -import QtQuick 2.0 +import QtQuick import "../../ui" StyleBase { diff --git a/nymea-app/styles/noir/Background.qml b/nymea-app/styles/noir/Background.qml index 9a4e71a5..10ca63bd 100644 --- a/nymea-app/styles/noir/Background.qml +++ b/nymea-app/styles/noir/Background.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import Nymea 1.0 +import QtQuick +import Nymea Rectangle { color: Style.backgroundColor diff --git a/nymea-app/styles/noir/Button.qml b/nymea-app/styles/noir/Button.qml index 4d93fd68..6fc06508 100644 --- a/nymea-app/styles/noir/Button.qml +++ b/nymea-app/styles/noir/Button.qml @@ -22,13 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 +import QtQuick import QtQuick.Templates 2.2 as T -import QtQuick.Controls 2.2 +import QtQuick.Controls import QtQuick.Controls.impl 2.2 -import QtQuick.Controls.Material 2.2 +import QtQuick.Controls.Material import QtQuick.Controls.Material.impl 2.2 -import Nymea 1.0 +import Nymea T.Button { id: control diff --git a/nymea-app/styles/noir/Page.qml b/nymea-app/styles/noir/Page.qml index a3e3dd1f..148ec72a 100644 --- a/nymea-app/styles/noir/Page.qml +++ b/nymea-app/styles/noir/Page.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 +import QtQuick import QtQuick.Templates 2.2 -import QtQuick.Controls.Material 2.2 -import Nymea 1.0 +import QtQuick.Controls.Material +import Nymea Page { background: Background {} diff --git a/nymea-app/styles/noir/Style.qml b/nymea-app/styles/noir/Style.qml index d22d3be4..c0bccd16 100644 --- a/nymea-app/styles/noir/Style.qml +++ b/nymea-app/styles/noir/Style.qml @@ -23,7 +23,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ pragma Singleton -import QtQuick 2.0 +import QtQuick import "../../ui" StyleBase { diff --git a/nymea-app/ui/Configuration.qml b/nymea-app/ui/Configuration.qml index efda6d70..60f5afb7 100644 --- a/nymea-app/ui/Configuration.qml +++ b/nymea-app/ui/Configuration.qml @@ -23,7 +23,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ pragma Singleton -import QtQuick 2.0 +import QtQuick ConfigurationBase { systemName: "nymea" diff --git a/nymea-app/ui/ConfigurationBase.qml b/nymea-app/ui/ConfigurationBase.qml index 29b887ce..9f77919d 100644 --- a/nymea-app/ui/ConfigurationBase.qml +++ b/nymea-app/ui/ConfigurationBase.qml @@ -22,7 +22,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 +import QtQuick Item { property string systemName: "" diff --git a/nymea-app/ui/KeyboardLoader.qml b/nymea-app/ui/KeyboardLoader.qml index 23b8c4a3..82fba9b1 100644 --- a/nymea-app/ui/KeyboardLoader.qml +++ b/nymea-app/ui/KeyboardLoader.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.4 -import QtQuick.Window 2.3 +import QtQuick +import QtQuick.Window Item { id: root @@ -40,8 +40,8 @@ Item { property var kbd: null property string virtualKeyboardString: ' - import QtQuick 2.8; - import QtQuick.VirtualKeyboard 2.1 + import QtQuick + import QtQuick.VirtualKeyboard InputPanel { id: inputPanel y: Qt.inputMethod.visible ? parent.height - inputPanel.height : parent.height diff --git a/nymea-app/ui/MagicPage.qml b/nymea-app/ui/MagicPage.qml index 1ba07b7e..642a627f 100644 --- a/nymea-app/ui/MagicPage.qml +++ b/nymea-app/ui/MagicPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "components" -import Nymea 1.0 Page { id: root @@ -99,8 +100,8 @@ Page { Connections { target: engine.ruleManager - onAddRuleReply: { - if (ruleError == RuleManager.RuleErrorNoError) { + onAddRuleReply: (commandId, ruleError, ruleId) => { + if (ruleError === RuleManager.RuleErrorNoError) { // print("should tag rule now:", d.editRulePage.rule.id, d.editRulePage.ruleIcon, d.editRulePage.ruleColor) // engine.tagsManager.tagRule(ruleId, "color", d.editRulePage.ruleColor) // engine.tagsManager.tagRule(ruleId, "icon", d.editRulePage.ruleIcon) @@ -112,8 +113,8 @@ Page { d.editRulePage.busy = false; } - onEditRuleReply: { - if (ruleError == RuleManager.RuleErrorNoError) { + onEditRuleReply: (commandId, ruleError) => { + if (ruleError === RuleManager.RuleErrorNoError) { // print("should tag rule now:", d.editRulePage.ruleIcon, d.editRulePage.ruleColor) engine.tagsManager.tagRule(d.editRulePage.rule.id, "color", d.editRulePage.ruleColor) engine.tagsManager.tagRule(d.editRulePage.rule.id, "icon", d.editRulePage.ruleIcon) diff --git a/nymea-app/ui/MainMenu.qml b/nymea-app/ui/MainMenu.qml index 5d0f16a5..998369a4 100644 --- a/nymea-app/ui/MainMenu.qml +++ b/nymea-app/ui/MainMenu.qml @@ -22,13 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Qt.labs.settings 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtCore +import Nymea +import NymeaApp.Utils + import "components" -import Nymea 1.0 -import NymeaApp.Utils 1.0 Drawer { id: root @@ -187,7 +188,7 @@ Drawer { enabled: topSectionLayout.configureConnections onClicked: { print("host is:", hostDelegate.configuredHost.uuid) - if (hostDelegate.configuredHost.uuid != "{00000000-0000-0000-0000-000000000000}") { + if (hostDelegate.configuredHost.uuid !== "{00000000-0000-0000-0000-000000000000}") { var popup = askCloseDialog.createObject(app, {uuid: hostDelegate.configuredHost.uuid, index: index}) popup.open(); } else { @@ -265,7 +266,7 @@ Drawer { fakeDragItem.y = Math.max(0, Math.min(hostsListView.height - fakeDragItem.height, originY - diff)) var hoveredIdx = hostsListView.indexAt(mouseX, mouseY) - if (hoveredIdx >= 0 && draggedIndex != hoveredIdx) { + if (hoveredIdx >= 0 && draggedIndex !== hoveredIdx) { print("moved", draggedIndex, "to", hoveredIdx) root.configuredHosts.move(draggedIndex, hoveredIdx) draggedIndex = hoveredIdx; diff --git a/nymea-app/ui/MainPage.qml b/nymea-app/ui/MainPage.qml index 38303ebb..23832c1f 100644 --- a/nymea-app/ui/MainPage.qml +++ b/nymea-app/ui/MainPage.qml @@ -22,15 +22,16 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtQuick.Window 2.3 -import Qt.labs.settings 1.0 -import Qt.labs.folderlistmodel 2.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtQuick.Window +import QtCore +import Qt.labs.folderlistmodel import Qt5Compat.GraphicalEffects -import Nymea 1.0 +import Nymea + import "components" import "delegates" import "mainviews" @@ -124,7 +125,7 @@ Page { Connections { target: engine.ruleManager - onAddRuleReply: { + onAddRuleReply: (commandId, ruleError, ruleId) => { d.editRulePage.busy = false if (d.editRulePage) { pageStack.pop(); diff --git a/nymea-app/ui/Nymea.qml b/nymea-app/ui/Nymea.qml index 237e3e44..4b777c5d 100644 --- a/nymea-app/ui/Nymea.qml +++ b/nymea-app/ui/Nymea.qml @@ -22,15 +22,16 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import Qt.labs.settings 1.0 -import Qt.labs.folderlistmodel 2.2 -import QtQuick.Window 2.3 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick.Controls.Material +import QtQuick.Controls +import QtQuick +import QtQuick.Layouts +import QtCore +import Qt.labs.folderlistmodel +import QtQuick.Window + +import Nymea +import NymeaApp.Utils ApplicationWindow { id: app @@ -567,7 +568,7 @@ ApplicationWindow { // by checking if the app becomes inactive right after the event. If not, it's probably a back // button press and we close ourselves. onClosing: { - if (Qt.platform.os == "android") { + if (Qt.platform.os === "android") { var handled = rootItem.handleAndroidBackButton(); if (!handled) { closeTimer.start() @@ -591,20 +592,20 @@ ApplicationWindow { showFiles: false } - // NOTE: If using a Dialog, make sure closePolicy does not contain Dialog.CloseOnPressOutside - // or the virtual keyboard will close when pressing it... + // // NOTE: If using a Dialog, make sure closePolicy does not contain Dialog.CloseOnPressOutside + // // or the virtual keyboard will close when pressing it... - // https://bugreports.qt.io/browse/QTBUG-56918 + // // https://bugreports.qt.io/browse/QTBUG-56918 KeyboardLoader { id: keyboardRect - parent: app.overlay + // parent: app.overlay z: 1 anchors { left: parent.left; bottom: parent.bottom; right: parent.right } } Image { id: splashScreen - parent: overlay + // parent: overlay source: "/ui/images/nymea-splash.svg" anchors.fill: parent fillMode: Image.PreserveAspectCrop diff --git a/nymea-app/ui/PushButtonAuthPage.qml b/nymea-app/ui/PushButtonAuthPage.qml index df702911..01ebd627 100644 --- a/nymea-app/ui/PushButtonAuthPage.qml +++ b/nymea-app/ui/PushButtonAuthPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "components" Page { diff --git a/nymea-app/ui/RootItem.qml b/nymea-app/ui/RootItem.qml index 735f5b8f..ed301478 100644 --- a/nymea-app/ui/RootItem.qml +++ b/nymea-app/ui/RootItem.qml @@ -22,14 +22,15 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.3 -import Qt.labs.settings 1.0 -import QtQuick.Window 2.12 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCore +import QtQuick.Window +import Nymea +import NymeaApp.Utils + import "components" import "connection" diff --git a/nymea-app/ui/SettingsPage.qml b/nymea-app/ui/SettingsPage.qml index e9756972..5f113aa8 100644 --- a/nymea-app/ui/SettingsPage.qml +++ b/nymea-app/ui/SettingsPage.qml @@ -22,12 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea +import NymeaApp.Utils import "components" Page { diff --git a/nymea-app/ui/StyleBase.qml b/nymea-app/ui/StyleBase.qml index 4208ec6e..5dda1587 100644 --- a/nymea-app/ui/StyleBase.qml +++ b/nymea-app/ui/StyleBase.qml @@ -22,7 +22,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 +import QtQuick Item { property color backgroundColor: "#fafafa" diff --git a/nymea-app/ui/appsettings/AboutPage.qml b/nymea-app/ui/appsettings/AboutPage.qml index c0338144..6398daab 100644 --- a/nymea-app/ui/appsettings/AboutPage.qml +++ b/nymea-app/ui/appsettings/AboutPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" SettingsPageBase { diff --git a/nymea-app/ui/appsettings/AppLogPage.qml b/nymea-app/ui/appsettings/AppLogPage.qml index fe073a99..52ae632e 100644 --- a/nymea-app/ui/appsettings/AppLogPage.qml +++ b/nymea-app/ui/appsettings/AppLogPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" Page { diff --git a/nymea-app/ui/appsettings/AppSettingsPage.qml b/nymea-app/ui/appsettings/AppSettingsPage.qml index 88732794..23592532 100644 --- a/nymea-app/ui/appsettings/AppSettingsPage.qml +++ b/nymea-app/ui/appsettings/AppSettingsPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" Page { diff --git a/nymea-app/ui/appsettings/DeveloperOptionsPage.qml b/nymea-app/ui/appsettings/DeveloperOptionsPage.qml index 743d7490..52d11f89 100644 --- a/nymea-app/ui/appsettings/DeveloperOptionsPage.qml +++ b/nymea-app/ui/appsettings/DeveloperOptionsPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" SettingsPageBase { diff --git a/nymea-app/ui/appsettings/LoggingCategories.qml b/nymea-app/ui/appsettings/LoggingCategories.qml index 44dbe86c..81d0fcab 100644 --- a/nymea-app/ui/appsettings/LoggingCategories.qml +++ b/nymea-app/ui/appsettings/LoggingCategories.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" SettingsPageBase { diff --git a/nymea-app/ui/appsettings/LookAndFeelSettingsPage.qml b/nymea-app/ui/appsettings/LookAndFeelSettingsPage.qml index 6e6d2b20..95657a19 100644 --- a/nymea-app/ui/appsettings/LookAndFeelSettingsPage.qml +++ b/nymea-app/ui/appsettings/LookAndFeelSettingsPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" SettingsPageBase { @@ -50,7 +51,7 @@ SettingsPageBase { model: styleController.allStyles currentIndex: styleController.allStyles.indexOf(styleController.currentStyle) - onActivated: { + onActivated: (index) => { styleController.currentStyle = model[index] } } @@ -88,7 +89,7 @@ SettingsPageBase { } } - onActivated: { + onActivated: (index) => { switch (currentIndex) { case 0: settings.viewMode = ApplicationWindow.Windowed; @@ -123,8 +124,8 @@ SettingsPageBase { id: unitsComboBox currentIndex: settings.units === "metric" ? 0 : 1 model: [ qsTr("Metric"), qsTr("Imperial") ] - onActivated: { - settings.units = index == 0 ? "metric" : "imperial"; + onActivated: (index) => { + settings.units = index === 0 ? "metric" : "imperial"; } } } diff --git a/nymea-app/ui/components/ActivityIndicator.qml b/nymea-app/ui/components/ActivityIndicator.qml index 529b26f2..294dcca2 100644 --- a/nymea-app/ui/components/ActivityIndicator.qml +++ b/nymea-app/ui/components/ActivityIndicator.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import Nymea 1.0 +import QtQuick +import Nymea Item { id: root diff --git a/nymea-app/ui/components/AutoSizeMenu.qml b/nymea-app/ui/components/AutoSizeMenu.qml index bbccc66f..a8727e45 100644 --- a/nymea-app/ui/components/AutoSizeMenu.qml +++ b/nymea-app/ui/components/AutoSizeMenu.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 +import QtQuick +import QtQuick.Controls Menu { modal: true diff --git a/nymea-app/ui/components/BackgroundFocusHandler.qml b/nymea-app/ui/components/BackgroundFocusHandler.qml index 4d7be7a3..b9f01a39 100644 --- a/nymea-app/ui/components/BackgroundFocusHandler.qml +++ b/nymea-app/ui/components/BackgroundFocusHandler.qml @@ -22,7 +22,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 +import QtQuick MouseArea { onClicked: { diff --git a/nymea-app/ui/components/BatteryStatusIcon.qml b/nymea-app/ui/components/BatteryStatusIcon.qml index 5a29a5fd..47225435 100644 --- a/nymea-app/ui/components/BatteryStatusIcon.qml +++ b/nymea-app/ui/components/BatteryStatusIcon.qml @@ -22,9 +22,9 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import Nymea +import NymeaApp.Utils ColorIcon { id: root @@ -42,12 +42,12 @@ ColorIcon { name: { if (!hasBatteryLevel) { if (isCritical) { - return "qrc:/icons/battery/battery-020.svg" + return "battery/battery-020" } - return "qrc:/icons/battery/battery-100.svg" + return "battery/battery-100" } var rounded = Math.round(batteryLevel / 10) * 10 - return "qrc:/icons/battery/battery-" + NymeaUtils.pad(rounded, 3) + return "battery/battery-" + NymeaUtils.pad(rounded, 3) } } diff --git a/nymea-app/ui/components/BigThingTile.qml b/nymea-app/ui/components/BigThingTile.qml index f14c06cb..a5e01747 100644 --- a/nymea-app/ui/components/BigThingTile.qml +++ b/nymea-app/ui/components/BigThingTile.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea BigTile { id: root diff --git a/nymea-app/ui/components/BigTile.qml b/nymea-app/ui/components/BigTile.qml index 80f8ecc2..e7720252 100644 --- a/nymea-app/ui/components/BigTile.qml +++ b/nymea-app/ui/components/BigTile.qml @@ -22,14 +22,16 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material + +import Nymea Item { id: root + implicitHeight: layout.implicitHeight + app.margins property alias header: headerContainer.children @@ -85,6 +87,7 @@ Item { anchors.fill: parent anchors.margins: app.margins / 2 radius: Style.cornerRadius + clip: true gradient: Gradient { GradientStop { @@ -100,6 +103,7 @@ Item { } } + ColumnLayout { id: layout spacing: 0 @@ -113,6 +117,7 @@ Item { height: childrenRect.height } + ItemDelegate { id: content Layout.fillWidth: true diff --git a/nymea-app/ui/components/BrightnessSlider.qml b/nymea-app/ui/components/BrightnessSlider.qml index 5ba2eb7e..0ecca7d7 100644 --- a/nymea-app/ui/components/BrightnessSlider.qml +++ b/nymea-app/ui/components/BrightnessSlider.qml @@ -22,9 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtGraphicalEffects 1.0 -import Nymea 1.0 +import QtQuick +import Qt5Compat.GraphicalEffects +import Nymea + import "../utils" Item { diff --git a/nymea-app/ui/components/BrowserContextMenu.qml b/nymea-app/ui/components/BrowserContextMenu.qml index 96c0db00..4d6bf141 100644 --- a/nymea-app/ui/components/BrowserContextMenu.qml +++ b/nymea-app/ui/components/BrowserContextMenu.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../delegates" NymeaDialog { diff --git a/nymea-app/ui/components/BusyOverlay.qml b/nymea-app/ui/components/BusyOverlay.qml index e75938c3..d8087f46 100644 --- a/nymea-app/ui/components/BusyOverlay.qml +++ b/nymea-app/ui/components/BusyOverlay.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Controls Rectangle { anchors.fill: parent diff --git a/nymea-app/ui/components/ButtonControls.qml b/nymea-app/ui/components/ButtonControls.qml index 3d2c7c68..20c5de25 100644 --- a/nymea-app/ui/components/ButtonControls.qml +++ b/nymea-app/ui/components/ButtonControls.qml @@ -22,11 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea RowLayout { id: root diff --git a/nymea-app/ui/components/CircleBackground.qml b/nymea-app/ui/components/CircleBackground.qml index 2ce39276..1bda4116 100644 --- a/nymea-app/ui/components/CircleBackground.qml +++ b/nymea-app/ui/components/CircleBackground.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtGraphicalEffects 1.0 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import Qt5Compat.GraphicalEffects +import Nymea + import "../utils" Item { diff --git a/nymea-app/ui/components/ClosableArrowAnimation.qml b/nymea-app/ui/components/ClosableArrowAnimation.qml index 28a027ac..2103c76f 100644 --- a/nymea-app/ui/components/ClosableArrowAnimation.qml +++ b/nymea-app/ui/components/ClosableArrowAnimation.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import Nymea 1.0 +import QtQuick +import Nymea Item { id: arrows diff --git a/nymea-app/ui/components/ClosablesControlLarge.qml b/nymea-app/ui/components/ClosablesControlLarge.qml index f4025503..c3d25035 100644 --- a/nymea-app/ui/components/ClosablesControlLarge.qml +++ b/nymea-app/ui/components/ClosablesControlLarge.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import QtGraphicalEffects 1.0 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Qt5Compat.GraphicalEffects +import Nymea + import "../customviews" Item { diff --git a/nymea-app/ui/components/ColorIcon.qml b/nymea-app/ui/components/ColorIcon.qml index ad60559c..af2e3b65 100644 --- a/nymea-app/ui/components/ColorIcon.qml +++ b/nymea-app/ui/components/ColorIcon.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.4 -import Nymea 1.0 +import QtQuick +import Nymea Item { id: icon diff --git a/nymea-app/ui/components/ColorPicker.qml b/nymea-app/ui/components/ColorPicker.qml index 510650e2..b2c221e0 100644 --- a/nymea-app/ui/components/ColorPicker.qml +++ b/nymea-app/ui/components/ColorPicker.qml @@ -22,9 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtGraphicalEffects 1.0 -import Nymea 1.0 +import QtQuick +import Qt5Compat.GraphicalEffects +import Nymea + import "../utils" Item { diff --git a/nymea-app/ui/components/ColorPickerCt.qml b/nymea-app/ui/components/ColorPickerCt.qml index d5329645..720725ee 100644 --- a/nymea-app/ui/components/ColorPickerCt.qml +++ b/nymea-app/ui/components/ColorPickerCt.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import Nymea 1.0 +import QtQuick +import Nymea Item { id: root diff --git a/nymea-app/ui/components/ColorPickerPre510.qml b/nymea-app/ui/components/ColorPickerPre510.qml index 42c0a0c7..11e9bc48 100644 --- a/nymea-app/ui/components/ColorPickerPre510.qml +++ b/nymea-app/ui/components/ColorPickerPre510.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import Nymea 1.0 +import QtQuick +import Nymea Item { id: root diff --git a/nymea-app/ui/components/ColorTemperaturePicker.qml b/nymea-app/ui/components/ColorTemperaturePicker.qml index 09b435c1..66c0f2bf 100644 --- a/nymea-app/ui/components/ColorTemperaturePicker.qml +++ b/nymea-app/ui/components/ColorTemperaturePicker.qml @@ -22,9 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtGraphicalEffects 1.0 -import Nymea 1.0 +import QtQuick +import Qt5Compat.GraphicalEffects +import Nymea + import "../utils" Item { diff --git a/nymea-app/ui/components/ConnectionInfoDialog.qml b/nymea-app/ui/components/ConnectionInfoDialog.qml index e6ef2bee..21d41b22 100644 --- a/nymea-app/ui/components/ConnectionInfoDialog.qml +++ b/nymea-app/ui/components/ConnectionInfoDialog.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import Nymea 1.0 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "qrc:/ui/connection" Dialog { diff --git a/nymea-app/ui/components/ConnectionStatusIcon.qml b/nymea-app/ui/components/ConnectionStatusIcon.qml index 65e7372a..b1dafa2b 100644 --- a/nymea-app/ui/components/ConnectionStatusIcon.qml +++ b/nymea-app/ui/components/ConnectionStatusIcon.qml @@ -22,9 +22,9 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import Nymea +import NymeaApp.Utils ColorIcon { id: root diff --git a/nymea-app/ui/components/DatePicker.qml b/nymea-app/ui/components/DatePicker.qml index 8d843f7b..205ed459 100644 --- a/nymea-app/ui/components/DatePicker.qml +++ b/nymea-app/ui/components/DatePicker.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea ColumnLayout { id: root diff --git a/nymea-app/ui/components/Dial.qml b/nymea-app/ui/components/Dial.qml index af4b2377..2ef01ee1 100644 --- a/nymea-app/ui/components/Dial.qml +++ b/nymea-app/ui/components/Dial.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.2 -import Nymea 1.0 -import QtQuick.Layouts 1.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../utils" Item { diff --git a/nymea-app/ui/components/EmptyViewPlaceholder.qml b/nymea-app/ui/components/EmptyViewPlaceholder.qml index c4285f1a..c1922a6b 100644 --- a/nymea-app/ui/components/EmptyViewPlaceholder.qml +++ b/nymea-app/ui/components/EmptyViewPlaceholder.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea ColumnLayout { id: root diff --git a/nymea-app/ui/components/ErrorDialog.qml b/nymea-app/ui/components/ErrorDialog.qml index 1a065d6a..35b80b88 100644 --- a/nymea-app/ui/components/ErrorDialog.qml +++ b/nymea-app/ui/components/ErrorDialog.qml @@ -22,9 +22,9 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts NymeaDialog { id: root diff --git a/nymea-app/ui/components/Graph.qml b/nymea-app/ui/components/Graph.qml index 16f85d67..dbbb363b 100644 --- a/nymea-app/ui/components/Graph.qml +++ b/nymea-app/ui/components/Graph.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.4 -import QtQuick.Controls 2.1 -import Nymea 1.0 -import QtQuick.Controls.Material 2.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import Nymea Item { id: root diff --git a/nymea-app/ui/components/GroupedListView.qml b/nymea-app/ui/components/GroupedListView.qml index eb75277c..5c5108e3 100644 --- a/nymea-app/ui/components/GroupedListView.qml +++ b/nymea-app/ui/components/GroupedListView.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 +import QtQuick +import QtQuick.Controls ListView { id: root diff --git a/nymea-app/ui/components/HeaderButton.qml b/nymea-app/ui/components/HeaderButton.qml index eea5c13b..22d2058e 100644 --- a/nymea-app/ui/components/HeaderButton.qml +++ b/nymea-app/ui/components/HeaderButton.qml @@ -22,9 +22,9 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import Nymea ToolButton { property alias imageSource: image.name diff --git a/nymea-app/ui/components/IconMenuItem.qml b/nymea-app/ui/components/IconMenuItem.qml index ac86dcfc..401430eb 100644 --- a/nymea-app/ui/components/IconMenuItem.qml +++ b/nymea-app/ui/components/IconMenuItem.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea MenuItem { id: root diff --git a/nymea-app/ui/components/Imprint.qml b/nymea-app/ui/components/Imprint.qml index 5430fa15..c09d2280 100644 --- a/nymea-app/ui/components/Imprint.qml +++ b/nymea-app/ui/components/Imprint.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea Item { diff --git a/nymea-app/ui/components/InfoPane.qml b/nymea-app/ui/components/InfoPane.qml index 3fb112c6..b1575171 100644 --- a/nymea-app/ui/components/InfoPane.qml +++ b/nymea-app/ui/components/InfoPane.qml @@ -22,11 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea InfoPaneBase { id: root diff --git a/nymea-app/ui/components/InfoPaneBase.qml b/nymea-app/ui/components/InfoPaneBase.qml index c1aef187..87fdf907 100644 --- a/nymea-app/ui/components/InfoPaneBase.qml +++ b/nymea-app/ui/components/InfoPaneBase.qml @@ -22,11 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea Item { id: root diff --git a/nymea-app/ui/components/KeypadButton.qml b/nymea-app/ui/components/KeypadButton.qml index d7e11c40..00aa6591 100644 --- a/nymea-app/ui/components/KeypadButton.qml +++ b/nymea-app/ui/components/KeypadButton.qml @@ -22,11 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import Nymea 1.0 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea Item { id: root diff --git a/nymea-app/ui/components/Led.qml b/nymea-app/ui/components/Led.qml index 76273b35..962d2136 100644 --- a/nymea-app/ui/components/Led.qml +++ b/nymea-app/ui/components/Led.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import Nymea 1.0 +import QtQuick +import Nymea Item { id: root diff --git a/nymea-app/ui/components/ListFilterInput.qml b/nymea-app/ui/components/ListFilterInput.qml index b0e6a3ad..ef34e151 100644 --- a/nymea-app/ui/components/ListFilterInput.qml +++ b/nymea-app/ui/components/ListFilterInput.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.6 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea + import "../components" import "../delegates" -import Nymea 1.0 Item { id: root diff --git a/nymea-app/ui/components/ListSectionHeader.qml b/nymea-app/ui/components/ListSectionHeader.qml index 38aad515..ec3e50c8 100644 --- a/nymea-app/ui/components/ListSectionHeader.qml +++ b/nymea-app/ui/components/ListSectionHeader.qml @@ -22,9 +22,9 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Layouts 1.3 -import QtQuick.Controls 2.2 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls ColumnLayout { width: parent.width diff --git a/nymea-app/ui/components/MainPageTabButton.qml b/nymea-app/ui/components/MainPageTabButton.qml index 863b9216..9d42fcfa 100644 --- a/nymea-app/ui/components/MainPageTabButton.qml +++ b/nymea-app/ui/components/MainPageTabButton.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts + +import Nymea TabButton { id: root diff --git a/nymea-app/ui/components/MainPageTile.qml b/nymea-app/ui/components/MainPageTile.qml index ecfe5d13..bb29e647 100644 --- a/nymea-app/ui/components/MainPageTile.qml +++ b/nymea-app/ui/components/MainPageTile.qml @@ -22,12 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts import Qt5Compat.GraphicalEffects +import Nymea Item { id: root @@ -36,6 +36,7 @@ Item { property alias fallbackIconName: fallbackIcon.name property alias iconColor: colorIcon.color property alias backgroundImage: backgroundImg.source + property string text property bool disconnected: false property bool isWireless: false @@ -99,7 +100,6 @@ Item { anchors.margins: app.margins / 2 source: backgroundImg maskSource: backgroundImgClipper -// visible: root.backgroundImage.length > 0 } ItemDelegate { @@ -141,7 +141,7 @@ Item { Item { Layout.fillWidth: true Layout.fillHeight: true - visible: backgroundImg.status !== Image.Ready && label.text != "" + visible: backgroundImg.status !== Image.Ready && label.text !== "" Label { id: label diff --git a/nymea-app/ui/components/MainViewBase.qml b/nymea-app/ui/components/MainViewBase.qml index aa3dc62a..6d8cf1b8 100644 --- a/nymea-app/ui/components/MainViewBase.qml +++ b/nymea-app/ui/components/MainViewBase.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" import "../delegates" @@ -52,6 +53,6 @@ Item { MouseArea { anchors.fill: parent preventStealing: true - onWheel: wheel.accepted = true + onWheel: (wheel) => wheel.accepted = true } } diff --git a/nymea-app/ui/components/MediaArtworkImage.qml b/nymea-app/ui/components/MediaArtworkImage.qml index a120a0bd..dc1d5b2a 100644 --- a/nymea-app/ui/components/MediaArtworkImage.qml +++ b/nymea-app/ui/components/MediaArtworkImage.qml @@ -22,11 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea Item { id: root diff --git a/nymea-app/ui/components/MediaBrowser.qml b/nymea-app/ui/components/MediaBrowser.qml index d1ebca29..e5b651dd 100644 --- a/nymea-app/ui/components/MediaBrowser.qml +++ b/nymea-app/ui/components/MediaBrowser.qml @@ -22,12 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import QtGraphicalEffects 1.0 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Qt5Compat.GraphicalEffects +import Nymea import "../delegates" diff --git a/nymea-app/ui/components/MediaControls.qml b/nymea-app/ui/components/MediaControls.qml index bdc4c10a..81d83e15 100644 --- a/nymea-app/ui/components/MediaControls.qml +++ b/nymea-app/ui/components/MediaControls.qml @@ -22,11 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea RowLayout { id: root diff --git a/nymea-app/ui/components/MediaPlayer.qml b/nymea-app/ui/components/MediaPlayer.qml index ec8078ed..dab53d0e 100644 --- a/nymea-app/ui/components/MediaPlayer.qml +++ b/nymea-app/ui/components/MediaPlayer.qml @@ -22,14 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import Nymea 1.0 -import NymeaApp.Utils 1.0 -import QtGraphicalEffects 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea +import NymeaApp.Utils import Qt5Compat.GraphicalEffects + import "../delegates" import "../utils" diff --git a/nymea-app/ui/components/MultiSelectionTabs.qml b/nymea-app/ui/components/MultiSelectionTabs.qml index 4a31aa7a..d62708f5 100644 --- a/nymea-app/ui/components/MultiSelectionTabs.qml +++ b/nymea-app/ui/components/MultiSelectionTabs.qml @@ -22,11 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.12 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.12 -import QtGraphicalEffects 1.0 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Qt5Compat.GraphicalEffects +import Nymea Rectangle { id: root diff --git a/nymea-app/ui/components/NavigationPad.qml b/nymea-app/ui/components/NavigationPad.qml index f151193d..94ba4ecf 100644 --- a/nymea-app/ui/components/NavigationPad.qml +++ b/nymea-app/ui/components/NavigationPad.qml @@ -22,11 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import Nymea 1.0 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.3 +import QtQuick +import Nymea +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts Item { id: root diff --git a/nymea-app/ui/components/NymeaDialog.qml b/nymea-app/ui/components/NymeaDialog.qml index 04f53667..eb64e977 100644 --- a/nymea-app/ui/components/NymeaDialog.qml +++ b/nymea-app/ui/components/NymeaDialog.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea Dialog { id: root @@ -46,15 +46,15 @@ Dialog { // onDestroye: root.destroy() // } - MouseArea { - parent: app.overlay - anchors.fill: parent - z: -1 - onPressed: { - print("Dialog: eating mouse press", root.title) - mouse.accepted = true - } - } + // MouseArea { + // // parent: app.overlay + // anchors.fill: parent + // z: -1 + // onPressed: { + // print("Dialog: eating mouse press", root.title) + // mouse.accepted = true + // } + // } header: Item { implicitHeight: headerRow.height + app.margins diff --git a/nymea-app/ui/components/NymeaHeader.qml b/nymea-app/ui/components/NymeaHeader.qml index becb97ef..7586f3bf 100644 --- a/nymea-app/ui/components/NymeaHeader.qml +++ b/nymea-app/ui/components/NymeaHeader.qml @@ -22,11 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import QtQuick.Controls.Material 2.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material +import Nymea Item { id: root diff --git a/nymea-app/ui/components/NymeaItemDelegate.qml b/nymea-app/ui/components/NymeaItemDelegate.qml index d7427cf9..fa649169 100644 --- a/nymea-app/ui/components/NymeaItemDelegate.qml +++ b/nymea-app/ui/components/NymeaItemDelegate.qml @@ -22,11 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import QtQuick.Controls.Material 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material +import Nymea // There's a bug in QtQuick.Controls' SwipeDelegate in that it appears with wrong // background when used in Popups/Dialogs So we need a non-swipable one for those cases diff --git a/nymea-app/ui/components/NymeaSpinBox.qml b/nymea-app/ui/components/NymeaSpinBox.qml index d252ae93..9c99bffb 100644 --- a/nymea-app/ui/components/NymeaSpinBox.qml +++ b/nymea-app/ui/components/NymeaSpinBox.qml @@ -22,9 +22,9 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls RowLayout { id: root diff --git a/nymea-app/ui/components/NymeaSwipeDelegate.qml b/nymea-app/ui/components/NymeaSwipeDelegate.qml index 412c4a38..48823855 100644 --- a/nymea-app/ui/components/NymeaSwipeDelegate.qml +++ b/nymea-app/ui/components/NymeaSwipeDelegate.qml @@ -22,11 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import QtQuick.Controls.Material 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material +import Nymea SwipeDelegate { id: root diff --git a/nymea-app/ui/components/NymeaTextField.qml b/nymea-app/ui/components/NymeaTextField.qml index 58b5c5fe..c23e48a9 100644 --- a/nymea-app/ui/components/NymeaTextField.qml +++ b/nymea-app/ui/components/NymeaTextField.qml @@ -22,26 +22,17 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Material 2.0 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl +import Nymea TextField { id: control property bool error: false - onEditingFinished: { - parent.forceActiveFocus() - } - - background: Rectangle { - y: control.height - height - control.bottomPadding + 8 - implicitWidth: 120 - height: control.activeFocus || control.hovered ? 2 : 1 - color: control.error ? Style.red : control.activeFocus ? Style.accentColor - : (control.hovered ? control.Material.primaryTextColor : control.Material.hintTextColor) - } + color: enabled ? ( control.error ? Style.red : Material.foreground) : Material.hintTextColor } diff --git a/nymea-app/ui/components/NymeaToolTip.qml b/nymea-app/ui/components/NymeaToolTip.qml index 34d31aa6..3750e640 100644 --- a/nymea-app/ui/components/NymeaToolTip.qml +++ b/nymea-app/ui/components/NymeaToolTip.qml @@ -22,9 +22,9 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 +import QtQuick import Qt5Compat.GraphicalEffects -import Nymea 1.0 +import Nymea Item { id: root diff --git a/nymea-app/ui/components/PasswordTextField.qml b/nymea-app/ui/components/PasswordTextField.qml index 243f5db8..324d63d9 100644 --- a/nymea-app/ui/components/PasswordTextField.qml +++ b/nymea-app/ui/components/PasswordTextField.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea ColumnLayout { id: root diff --git a/nymea-app/ui/components/ProgressButton.qml b/nymea-app/ui/components/ProgressButton.qml index ed5333dc..f6bfeab5 100644 --- a/nymea-app/ui/components/ProgressButton.qml +++ b/nymea-app/ui/components/ProgressButton.qml @@ -22,9 +22,9 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import Nymea Item { id: root diff --git a/nymea-app/ui/components/RemoveThingMethodDialog.qml b/nymea-app/ui/components/RemoveThingMethodDialog.qml index 73461108..da9039e4 100644 --- a/nymea-app/ui/components/RemoveThingMethodDialog.qml +++ b/nymea-app/ui/components/RemoveThingMethodDialog.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea Dialog { id: root diff --git a/nymea-app/ui/components/SelectionTabs.qml b/nymea-app/ui/components/SelectionTabs.qml index d8448874..5c0a0568 100644 --- a/nymea-app/ui/components/SelectionTabs.qml +++ b/nymea-app/ui/components/SelectionTabs.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea Rectangle { id: root diff --git a/nymea-app/ui/components/SettingsPageBase.qml b/nymea-app/ui/components/SettingsPageBase.qml index 98c3876b..a26b5649 100644 --- a/nymea-app/ui/components/SettingsPageBase.qml +++ b/nymea-app/ui/components/SettingsPageBase.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea Page { id: root diff --git a/nymea-app/ui/components/SettingsPageSectionHeader.qml b/nymea-app/ui/components/SettingsPageSectionHeader.qml index 729d6c0e..9668fa66 100644 --- a/nymea-app/ui/components/SettingsPageSectionHeader.qml +++ b/nymea-app/ui/components/SettingsPageSectionHeader.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea Label { Layout.fillWidth: true diff --git a/nymea-app/ui/components/SettingsTile.qml b/nymea-app/ui/components/SettingsTile.qml index bfb53ee3..491bf29a 100644 --- a/nymea-app/ui/components/SettingsTile.qml +++ b/nymea-app/ui/components/SettingsTile.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea BigTile { id: root diff --git a/nymea-app/ui/components/SetupStatusIcon.qml b/nymea-app/ui/components/SetupStatusIcon.qml index fbf31194..25d132f1 100644 --- a/nymea-app/ui/components/SetupStatusIcon.qml +++ b/nymea-app/ui/components/SetupStatusIcon.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import Nymea 1.0 +import QtQuick +import Nymea ColorIcon { id: root diff --git a/nymea-app/ui/components/ShuffleRepeatVolumeControl.qml b/nymea-app/ui/components/ShuffleRepeatVolumeControl.qml index 3c2a96aa..e37da75f 100644 --- a/nymea-app/ui/components/ShuffleRepeatVolumeControl.qml +++ b/nymea-app/ui/components/ShuffleRepeatVolumeControl.qml @@ -22,12 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtCharts 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts +import Nymea RowLayout { id: root diff --git a/nymea-app/ui/components/ShutterControls.qml b/nymea-app/ui/components/ShutterControls.qml index 81c670f2..535a3771 100644 --- a/nymea-app/ui/components/ShutterControls.qml +++ b/nymea-app/ui/components/ShutterControls.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea Item { id: root diff --git a/nymea-app/ui/components/SmartMeterChart.qml b/nymea-app/ui/components/SmartMeterChart.qml index 205f1c78..26df40e3 100644 --- a/nymea-app/ui/components/SmartMeterChart.qml +++ b/nymea-app/ui/components/SmartMeterChart.qml @@ -22,12 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import QtCharts 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts +import Nymea ChartView { id: root diff --git a/nymea-app/ui/components/StateDial.qml b/nymea-app/ui/components/StateDial.qml index 7829021c..3f69ca3a 100644 --- a/nymea-app/ui/components/StateDial.qml +++ b/nymea-app/ui/components/StateDial.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.2 -import Nymea 1.0 -import QtQuick.Layouts 1.2 +import QtQuick +import QtQuick.Controls +import Nymea +import QtQuick.Layouts + import "../utils" Item { diff --git a/nymea-app/ui/components/SwipeDelegateGroup.qml b/nymea-app/ui/components/SwipeDelegateGroup.qml index ab1196e2..9a5c3798 100644 --- a/nymea-app/ui/components/SwipeDelegateGroup.qml +++ b/nymea-app/ui/components/SwipeDelegateGroup.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 +import QtQuick +import QtQuick.Controls Item { id: swipeGroup diff --git a/nymea-app/ui/components/ThinDivider.qml b/nymea-app/ui/components/ThinDivider.qml index 10391da1..fe6cd6d9 100644 --- a/nymea-app/ui/components/ThinDivider.qml +++ b/nymea-app/ui/components/ThinDivider.qml @@ -22,9 +22,9 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import QtQuick.Layouts 1.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import Nymea Rectangle { height: 1 diff --git a/nymea-app/ui/components/ThingContextMenu.qml b/nymea-app/ui/components/ThingContextMenu.qml index e68862e7..ddfd1fcb 100644 --- a/nymea-app/ui/components/ThingContextMenu.qml +++ b/nymea-app/ui/components/ThingContextMenu.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea AutoSizeMenu { id: root diff --git a/nymea-app/ui/components/ThingInfoPane.qml b/nymea-app/ui/components/ThingInfoPane.qml index 23d62cd4..74710499 100644 --- a/nymea-app/ui/components/ThingInfoPane.qml +++ b/nymea-app/ui/components/ThingInfoPane.qml @@ -22,11 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea InfoPaneBase { id: root diff --git a/nymea-app/ui/components/ThingStatusIcons.qml b/nymea-app/ui/components/ThingStatusIcons.qml index 53525b3d..94a53cc1 100644 --- a/nymea-app/ui/components/ThingStatusIcons.qml +++ b/nymea-app/ui/components/ThingStatusIcons.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea RowLayout { id: root diff --git a/nymea-app/ui/components/ThrottledSlider.qml b/nymea-app/ui/components/ThrottledSlider.qml index ef18d2a8..196c4c60 100644 --- a/nymea-app/ui/components/ThrottledSlider.qml +++ b/nymea-app/ui/components/ThrottledSlider.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Controls Item { id: root diff --git a/nymea-app/ui/components/TimePicker.qml b/nymea-app/ui/components/TimePicker.qml index 772dc9e6..17aad19a 100644 --- a/nymea-app/ui/components/TimePicker.qml +++ b/nymea-app/ui/components/TimePicker.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea ColumnLayout { id: root diff --git a/nymea-app/ui/components/UpdateRunningOverlay.qml b/nymea-app/ui/components/UpdateRunningOverlay.qml index 1541ec0d..636fc458 100644 --- a/nymea-app/ui/components/UpdateRunningOverlay.qml +++ b/nymea-app/ui/components/UpdateRunningOverlay.qml @@ -22,11 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea Rectangle { anchors.fill: parent diff --git a/nymea-app/ui/components/UpdateStatusIcon.qml b/nymea-app/ui/components/UpdateStatusIcon.qml index d7a3b78c..d255d24e 100644 --- a/nymea-app/ui/components/UpdateStatusIcon.qml +++ b/nymea-app/ui/components/UpdateStatusIcon.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import Nymea 1.0 +import QtQuick +import Nymea ColorIcon { id: root diff --git a/nymea-app/ui/components/WebViewWrapper.qml b/nymea-app/ui/components/WebViewWrapper.qml index a2c979d0..601f7aec 100644 --- a/nymea-app/ui/components/WebViewWrapper.qml +++ b/nymea-app/ui/components/WebViewWrapper.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import QtWebView 1.1 +import QtQuick +import QtWebView // This is needed because we can only load this on-demand but // *deployqt will not include the module if there isn't a actual qml file importing it diff --git a/nymea-app/ui/components/WizardPageBase.qml b/nymea-app/ui/components/WizardPageBase.qml index 4b200ba5..c8a7bf3a 100644 --- a/nymea-app/ui/components/WizardPageBase.qml +++ b/nymea-app/ui/components/WizardPageBase.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" -import Nymea 1.0 Page { id: root @@ -75,7 +76,8 @@ Page { Row { id: additionalIcons - anchors { right: parent.right; top: parent.top } + Layout.alignment: Qt.AlignTop | Qt.AlignRight + //anchors { right: parent.right; top: parent.top } visible: !d.configOverlay width: visible ? implicitWidth : 0 Repeater { diff --git a/nymea-app/ui/connection/CertificateDialog.qml b/nymea-app/ui/connection/CertificateDialog.qml index 6647b1f6..92c4647e 100644 --- a/nymea-app/ui/connection/CertificateDialog.qml +++ b/nymea-app/ui/connection/CertificateDialog.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" Dialog { diff --git a/nymea-app/ui/connection/CertificateErrorDialog.qml b/nymea-app/ui/connection/CertificateErrorDialog.qml index 13a65bba..0e2127f1 100644 --- a/nymea-app/ui/connection/CertificateErrorDialog.qml +++ b/nymea-app/ui/connection/CertificateErrorDialog.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" NymeaDialog { diff --git a/nymea-app/ui/connection/ConnectingPage.qml b/nymea-app/ui/connection/ConnectingPage.qml index 8f9c3e5b..7ab6a8e3 100644 --- a/nymea-app/ui/connection/ConnectingPage.qml +++ b/nymea-app/ui/connection/ConnectingPage.qml @@ -22,13 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 -import "../components" +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea +import "../components" Page { id: root diff --git a/nymea-app/ui/connection/ConnectionWizard.qml b/nymea-app/ui/connection/ConnectionWizard.qml index 0d040c4a..c309fcc4 100644 --- a/nymea-app/ui/connection/ConnectionWizard.qml +++ b/nymea-app/ui/connection/ConnectionWizard.qml @@ -22,13 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.2 -import Qt.labs.settings 1.1 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtCore +import Nymea import "../components" -import Nymea 1.0 WizardPageBase { id: root @@ -67,7 +67,7 @@ WizardPageBase { ColorIcon { anchors.centerIn: parent size: Math.min(parent.width, parent.height, Style.hugeIconSize * 2) - name: "nymea-logo" + name: "qrc:/ui/images/nymea-logo.svg" } } @@ -98,7 +98,7 @@ WizardPageBase { font: Style.smallFont text: qsTr("Please follow the installation instructions on %1 to install a nymea system.").arg('nymea.io') horizontalAlignment: Text.AlignHCenter - onLinkActivated: Qt.openUrlExternally(link) + onLinkActivated: (link) => Qt.openUrlExternally(link) } } Item { Layout.fillHeight: true } @@ -353,7 +353,7 @@ WizardPageBase { Layout.margins: Style.margins fillMode: Image.PreserveAspectFit sourceSize.width: width - source: "qrc:/icons/setupwizard/wired-connection.svg" + source: "qrc:/ui/images/setupwizard/wired-connection.svg" } } } @@ -374,7 +374,7 @@ WizardPageBase { Layout.margins: Style.margins fillMode: Image.PreserveAspectFit sourceSize.width: width - source: "qrc:/icons/setupwizard/wireless-connection.svg" + source: "qrc:/ui/images/setupwizard/wireless-connection.svg" } } } @@ -661,7 +661,6 @@ WizardPageBase { NymeaTextField { id: ssidTextField Layout.fillWidth: true - } Label { diff --git a/nymea-app/ui/connection/LoginPage.qml b/nymea-app/ui/connection/LoginPage.qml index f74b644a..599f2926 100644 --- a/nymea-app/ui/connection/LoginPage.qml +++ b/nymea-app/ui/connection/LoginPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" SettingsPageBase { @@ -125,8 +126,8 @@ SettingsPageBase { ? Qt.ImhEmailCharactersOnly | Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText : Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText error: loginForm.showErrors && !acceptableInput - validator: RegExpValidator { - regExp: /[a-zA-Z0-9_\\.+-@]{3,}/ + validator: RegularExpressionValidator { + regularExpression: /[a-zA-Z0-9_\\.+-@]{3,}/ } } Label { diff --git a/nymea-app/ui/connection/ManualConnectionEntry.qml b/nymea-app/ui/connection/ManualConnectionEntry.qml index 558a05ea..a468fbfa 100644 --- a/nymea-app/ui/connection/ManualConnectionEntry.qml +++ b/nymea-app/ui/connection/ManualConnectionEntry.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" -import Nymea 1.0 ColumnLayout { diff --git a/nymea-app/ui/connection/SetupWizard.qml b/nymea-app/ui/connection/SetupWizard.qml index 47455cf7..f9f4e641 100644 --- a/nymea-app/ui/connection/SetupWizard.qml +++ b/nymea-app/ui/connection/SetupWizard.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" Page { diff --git a/nymea-app/ui/customviews/GarageController.qml b/nymea-app/ui/customviews/GarageController.qml index 444be732..0e8aaf08 100644 --- a/nymea-app/ui/customviews/GarageController.qml +++ b/nymea-app/ui/customviews/GarageController.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Layouts 1.1 -import QtQuick.Controls 2.1 -import QtGraphicalEffects 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Qt5Compat.GraphicalEffects +import Nymea + import "../components" -import Nymea 1.0 Item { id: root diff --git a/nymea-app/ui/customviews/GenericTypeGraph.qml b/nymea-app/ui/customviews/GenericTypeGraph.qml index 2d63ea5b..d1f61773 100644 --- a/nymea-app/ui/customviews/GenericTypeGraph.qml +++ b/nymea-app/ui/customviews/GenericTypeGraph.qml @@ -22,15 +22,16 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts +import Nymea +import NymeaApp.Utils + import "../components" import "../customviews" -import QtCharts 2.2 Item { id: root diff --git a/nymea-app/ui/customviews/GenericTypeLogView.qml b/nymea-app/ui/customviews/GenericTypeLogView.qml index c3b362c4..abac772f 100644 --- a/nymea-app/ui/customviews/GenericTypeLogView.qml +++ b/nymea-app/ui/customviews/GenericTypeLogView.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" Item { diff --git a/nymea-app/ui/customviews/MultiStateChart.qml b/nymea-app/ui/customviews/MultiStateChart.qml index 15cb7daf..2a499c51 100644 --- a/nymea-app/ui/customviews/MultiStateChart.qml +++ b/nymea-app/ui/customviews/MultiStateChart.qml @@ -22,15 +22,16 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts +import Nymea +import NymeaApp.Utils + import "../components" import "../customviews" -import QtCharts 2.2 Item { id: root @@ -248,7 +249,7 @@ Item { } } - onEntriesAddedIdx: { + onEntriesAddedIdx: (index, count) => { print("**** entries added", index, count, "entries in series:", series.count, "in model", logsModel.count) for (var i = 0; i < count; i++) { var entry = logsModel.get(i) @@ -301,7 +302,7 @@ Item { print("added entries. now in series:", series.count) } - onEntriesRemoved: { + onEntriesRemoved: (index, count) => { print("removing:", index, count, series.count) if (stateType.type.toLowerCase() == "bool") { series.removePoints(index * 2, count * 2) diff --git a/nymea-app/ui/customviews/SensorView.qml b/nymea-app/ui/customviews/SensorView.qml index d640b931..1c995cf7 100644 --- a/nymea-app/ui/customviews/SensorView.qml +++ b/nymea-app/ui/customviews/SensorView.qml @@ -22,13 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Layouts 1.1 -import QtQuick.Controls 2.3 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Qt5Compat.GraphicalEffects +import Nymea +import NymeaApp.Utils + import "qrc:/ui/components" -import QtGraphicalEffects 1.0 Item { id: root diff --git a/nymea-app/ui/customviews/StateChart.qml b/nymea-app/ui/customviews/StateChart.qml index 403934f7..b88bb3d3 100644 --- a/nymea-app/ui/customviews/StateChart.qml +++ b/nymea-app/ui/customviews/StateChart.qml @@ -22,15 +22,16 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts +import Nymea +import NymeaApp.Utils + import "../components" import "../customviews" -import QtCharts 2.2 Item { id: root @@ -106,7 +107,7 @@ Item { property double minValue property double maxValue - onEntriesAddedIdx: { + onEntriesAddedIdx: (index, count) => { // print("**** entries added", index, count, "entries in series:", valueSeries.count, "in model", logsModel.count) for (var i = 0; i < count; i++) { var entry = logsModel.get(i) @@ -157,7 +158,7 @@ Item { print("added entries. now in series:", valueSeries.count) } - onEntriesRemoved: { + onEntriesRemoved: (index, count) => { print("removing:", index, count, valueSeries.count) if (root.stateType.type.toLowerCase() == "bool") { valueSeries.removePoints(index * 2, count * 2) diff --git a/nymea-app/ui/customviews/ThermostatController.qml b/nymea-app/ui/customviews/ThermostatController.qml index 2433616f..b0799958 100644 --- a/nymea-app/ui/customviews/ThermostatController.qml +++ b/nymea-app/ui/customviews/ThermostatController.qml @@ -22,14 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../utils" import "../components" - Item { id: root diff --git a/nymea-app/ui/customviews/WeatherView.qml b/nymea-app/ui/customviews/WeatherView.qml index 9b4802c8..9422d026 100644 --- a/nymea-app/ui/customviews/WeatherView.qml +++ b/nymea-app/ui/customviews/WeatherView.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Layouts 1.1 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea + import "../components" -import Nymea 1.0 Item { id: root diff --git a/nymea-app/ui/delegates/ActionDelegate.qml b/nymea-app/ui/delegates/ActionDelegate.qml index 86847064..39db3915 100644 --- a/nymea-app/ui/delegates/ActionDelegate.qml +++ b/nymea-app/ui/delegates/ActionDelegate.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material +import Nymea + import "../components" ItemDelegate { @@ -280,7 +281,7 @@ ItemDelegate { currentIndex: paramType.allowedValues.indexOf(value) property var paramType: null property var value: null - onActivated: { + onActivated: (index) => { value = paramType.allowedValues[index] var params = []; var param1 = new Object(); diff --git a/nymea-app/ui/delegates/BrowserItemDelegate.qml b/nymea-app/ui/delegates/BrowserItemDelegate.qml index b050389d..6606b933 100644 --- a/nymea-app/ui/delegates/BrowserItemDelegate.qml +++ b/nymea-app/ui/delegates/BrowserItemDelegate.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" NymeaSwipeDelegate { diff --git a/nymea-app/ui/delegates/InterfaceTile.qml b/nymea-app/ui/delegates/InterfaceTile.qml index 63e344bc..6c587b22 100644 --- a/nymea-app/ui/delegates/InterfaceTile.qml +++ b/nymea-app/ui/delegates/InterfaceTile.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import QtQuick.Controls.Material 2.2 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material +import Nymea +import NymeaApp.Utils + import "../components" MainPageTile { diff --git a/nymea-app/ui/delegates/ParamDelegate.qml b/nymea-app/ui/delegates/ParamDelegate.qml index 5e77dc0f..6819d759 100644 --- a/nymea-app/ui/delegates/ParamDelegate.qml +++ b/nymea-app/ui/delegates/ParamDelegate.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material +import Nymea + import "../components" ItemDelegate { @@ -282,7 +283,7 @@ ItemDelegate { text: Types.toUiValue(modelData, root.paramType.unit) + ( root.paramType.unit != Types.UnitNone ? " " + Types.toUiUnit(root.paramType.unit) : "") highlighted: control.highlightedIndex === index } - onActivated: { + onActivated: (index) => { root.param.value = root.paramType.allowedValues[index] } Component.onCompleted: { diff --git a/nymea-app/ui/delegates/ParamDescriptorDelegate.qml b/nymea-app/ui/delegates/ParamDescriptorDelegate.qml index 29810cf5..ba66a7bb 100644 --- a/nymea-app/ui/delegates/ParamDescriptorDelegate.qml +++ b/nymea-app/ui/delegates/ParamDescriptorDelegate.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.4 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" ItemDelegate { diff --git a/nymea-app/ui/delegates/SensorListDelegate.qml b/nymea-app/ui/delegates/SensorListDelegate.qml index 924d63ba..eafe0a31 100644 --- a/nymea-app/ui/delegates/SensorListDelegate.qml +++ b/nymea-app/ui/delegates/SensorListDelegate.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" BigThingTile { diff --git a/nymea-app/ui/delegates/StateDelegate.qml b/nymea-app/ui/delegates/StateDelegate.qml index 2408c086..97bf68e5 100644 --- a/nymea-app/ui/delegates/StateDelegate.qml +++ b/nymea-app/ui/delegates/StateDelegate.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material +import Nymea + import "../components" ItemDelegate { @@ -270,7 +271,7 @@ ItemDelegate { text: Types.toUiValue(modelData, root.stateType.unit) + ( root.stateType.unit != Types.UnitNone ? " " + Types.toUiUnit(root.stateType.unit) : "") highlighted: control.highlightedIndex === index } - onActivated: { + onActivated: (index) => { root.param.value = root.stateType.allowedValues[index] } Component.onCompleted: { diff --git a/nymea-app/ui/delegates/ThingDelegate.qml b/nymea-app/ui/delegates/ThingDelegate.qml index 495cb099..5535631d 100644 --- a/nymea-app/ui/delegates/ThingDelegate.qml +++ b/nymea-app/ui/delegates/ThingDelegate.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" -import Nymea 1.0 NymeaSwipeDelegate { id: root diff --git a/nymea-app/ui/delegates/ThingTile.qml b/nymea-app/ui/delegates/ThingTile.qml index 4f67f26b..93cf8e3f 100644 --- a/nymea-app/ui/delegates/ThingTile.qml +++ b/nymea-app/ui/delegates/ThingTile.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import QtQuick.Controls.Material 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material +import Nymea + import "../components" MainPageTile { diff --git a/nymea-app/ui/delegates/statedelegates/CheckboxDelegate.qml b/nymea-app/ui/delegates/statedelegates/CheckboxDelegate.qml index aafdd610..ad6a5960 100644 --- a/nymea-app/ui/delegates/statedelegates/CheckboxDelegate.qml +++ b/nymea-app/ui/delegates/statedelegates/CheckboxDelegate.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../../components" CheckBox { diff --git a/nymea-app/ui/delegates/statedelegates/ColorDelegate.qml b/nymea-app/ui/delegates/statedelegates/ColorDelegate.qml index b8ec635b..cf8ef3d6 100644 --- a/nymea-app/ui/delegates/statedelegates/ColorDelegate.qml +++ b/nymea-app/ui/delegates/statedelegates/ColorDelegate.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../../components" Item { diff --git a/nymea-app/ui/delegates/statedelegates/ComboBoxDelegate.qml b/nymea-app/ui/delegates/statedelegates/ComboBoxDelegate.qml index a2eced94..d21b5735 100644 --- a/nymea-app/ui/delegates/statedelegates/ComboBoxDelegate.qml +++ b/nymea-app/ui/delegates/statedelegates/ComboBoxDelegate.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../../components" ComboBox { @@ -51,7 +52,7 @@ ComboBox { model: ListModel { id: listModel } - onActivated: changed(model.get(index).value) + onActivated: (index) => changed(model.get(index).value) textRole: "label" Component.onCompleted: { print("completed. values", possibleValues, "value", root.value) diff --git a/nymea-app/ui/delegates/statedelegates/DateTimeDelegate.qml b/nymea-app/ui/delegates/statedelegates/DateTimeDelegate.qml index cf646182..cd9d36a6 100644 --- a/nymea-app/ui/delegates/statedelegates/DateTimeDelegate.qml +++ b/nymea-app/ui/delegates/statedelegates/DateTimeDelegate.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../../components" Label { diff --git a/nymea-app/ui/delegates/statedelegates/LabelDelegate.qml b/nymea-app/ui/delegates/statedelegates/LabelDelegate.qml index 2141ab4c..5ba36d33 100644 --- a/nymea-app/ui/delegates/statedelegates/LabelDelegate.qml +++ b/nymea-app/ui/delegates/statedelegates/LabelDelegate.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../../components" Label { diff --git a/nymea-app/ui/delegates/statedelegates/LedDelegate.qml b/nymea-app/ui/delegates/statedelegates/LedDelegate.qml index c954ab34..cdeb4931 100644 --- a/nymea-app/ui/delegates/statedelegates/LedDelegate.qml +++ b/nymea-app/ui/delegates/statedelegates/LedDelegate.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../../components" Item { diff --git a/nymea-app/ui/delegates/statedelegates/ListDelegate.qml b/nymea-app/ui/delegates/statedelegates/ListDelegate.qml index 0395cc96..d120cc91 100644 --- a/nymea-app/ui/delegates/statedelegates/ListDelegate.qml +++ b/nymea-app/ui/delegates/statedelegates/ListDelegate.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../../components" Label { diff --git a/nymea-app/ui/delegates/statedelegates/NumberLabelDelegate.qml b/nymea-app/ui/delegates/statedelegates/NumberLabelDelegate.qml index dfcbd81a..ec99e426 100644 --- a/nymea-app/ui/delegates/statedelegates/NumberLabelDelegate.qml +++ b/nymea-app/ui/delegates/statedelegates/NumberLabelDelegate.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../../components" Label { diff --git a/nymea-app/ui/delegates/statedelegates/SliderDelegate.qml b/nymea-app/ui/delegates/statedelegates/SliderDelegate.qml index 733d7443..d4360ebc 100644 --- a/nymea-app/ui/delegates/statedelegates/SliderDelegate.qml +++ b/nymea-app/ui/delegates/statedelegates/SliderDelegate.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../../components" RowLayout { diff --git a/nymea-app/ui/delegates/statedelegates/SpinBoxDelegate.qml b/nymea-app/ui/delegates/statedelegates/SpinBoxDelegate.qml index 4e65ea66..bee05013 100644 --- a/nymea-app/ui/delegates/statedelegates/SpinBoxDelegate.qml +++ b/nymea-app/ui/delegates/statedelegates/SpinBoxDelegate.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../../components" SpinBox { diff --git a/nymea-app/ui/delegates/statedelegates/SwitchDelegate.qml b/nymea-app/ui/delegates/statedelegates/SwitchDelegate.qml index 83875a62..e25a75d0 100644 --- a/nymea-app/ui/delegates/statedelegates/SwitchDelegate.qml +++ b/nymea-app/ui/delegates/statedelegates/SwitchDelegate.qml @@ -22,12 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea -import Nymea 1.0 import "../../components" Switch { diff --git a/nymea-app/ui/delegates/statedelegates/TextFieldDelegate.qml b/nymea-app/ui/delegates/statedelegates/TextFieldDelegate.qml index 15fc9ba4..2e4a761d 100644 --- a/nymea-app/ui/delegates/statedelegates/TextFieldDelegate.qml +++ b/nymea-app/ui/delegates/statedelegates/TextFieldDelegate.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../../components" TextField { diff --git a/nymea-app/ui/devicelistpages/AwningThingsListPage.qml b/nymea-app/ui/devicelistpages/AwningThingsListPage.qml index 6f0561e8..15f97428 100644 --- a/nymea-app/ui/devicelistpages/AwningThingsListPage.qml +++ b/nymea-app/ui/devicelistpages/AwningThingsListPage.qml @@ -22,7 +22,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 +import QtQuick ClosablesThingsListPage { title: qsTr("Awnings") diff --git a/nymea-app/ui/devicelistpages/BlindThingsListPage.qml b/nymea-app/ui/devicelistpages/BlindThingsListPage.qml index 4e6a6411..0680f4fa 100644 --- a/nymea-app/ui/devicelistpages/BlindThingsListPage.qml +++ b/nymea-app/ui/devicelistpages/BlindThingsListPage.qml @@ -22,7 +22,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 +import QtQuick ClosablesThingsListPage { title: qsTr("Blinds") diff --git a/nymea-app/ui/devicelistpages/ClosablesThingsListPage.qml b/nymea-app/ui/devicelistpages/ClosablesThingsListPage.qml index 3761bd23..a818e01f 100644 --- a/nymea-app/ui/devicelistpages/ClosablesThingsListPage.qml +++ b/nymea-app/ui/devicelistpages/ClosablesThingsListPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import QtGraphicalEffects 1.0 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Qt5Compat.GraphicalEffects +import Nymea + import "../components" ThingsListPageBase { diff --git a/nymea-app/ui/devicelistpages/GarageThingsListPage.qml b/nymea-app/ui/devicelistpages/GarageThingsListPage.qml index 4ac278c4..1da5ae22 100644 --- a/nymea-app/ui/devicelistpages/GarageThingsListPage.qml +++ b/nymea-app/ui/devicelistpages/GarageThingsListPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../delegates" diff --git a/nymea-app/ui/devicelistpages/GenericThingsListPage.qml b/nymea-app/ui/devicelistpages/GenericThingsListPage.qml index 9c0db0cb..a272c2da 100644 --- a/nymea-app/ui/devicelistpages/GenericThingsListPage.qml +++ b/nymea-app/ui/devicelistpages/GenericThingsListPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../delegates" diff --git a/nymea-app/ui/devicelistpages/LightThingsListPage.qml b/nymea-app/ui/devicelistpages/LightThingsListPage.qml index a8a5e6ae..5b291bc7 100644 --- a/nymea-app/ui/devicelistpages/LightThingsListPage.qml +++ b/nymea-app/ui/devicelistpages/LightThingsListPage.qml @@ -22,13 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import QtGraphicalEffects 1.0 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Qt5Compat.GraphicalEffects +import Nymea +import NymeaApp.Utils + import "../components" import "../utils" diff --git a/nymea-app/ui/devicelistpages/MediaDeviceListPage.qml b/nymea-app/ui/devicelistpages/MediaDeviceListPage.qml index 369eb432..435b29e4 100644 --- a/nymea-app/ui/devicelistpages/MediaDeviceListPage.qml +++ b/nymea-app/ui/devicelistpages/MediaDeviceListPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 -import QtGraphicalEffects 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Qt5Compat.GraphicalEffects +import Nymea + import "../components" ThingsListPageBase { @@ -140,43 +141,35 @@ ThingsListPageBase { } } - Rectangle { - id: maskRect - anchors.centerIn: parent - height: parent.width - width: parent.height - radius: Style.cornerRadius - gradient: Gradient { - GradientStop { position: 0; color: "#00FF0000" } - GradientStop { position: 0.2; color: "#15FF0000" } - GradientStop { position: 1; color: "#FFFF0000" } - } - } + // Rectangle { + // id: maskRect + // anchors.centerIn: parent + // height: parent.width + // width: parent.height + // radius: Style.cornerRadius + // gradient: Gradient { + // orientation: Gradient.Horizontal + // GradientStop { position: 0; color: "#00FF0000" } + // GradientStop { position: 0.2; color: "#15FF0000" } + // GradientStop { position: 1; color: "#FFFF0000" } + // } + // } - ShaderEffect { - anchors.fill: parent - property variant source: ShaderEffectSource { - sourceItem: artworkContainer - hideSource: true - } - property variant mask: ShaderEffectSource { - sourceItem: maskRect - hideSource: true - } + // ShaderEffect { + // anchors.fill: parent + // property variant source: ShaderEffectSource { + // format: ShaderEffectSource.RGBA8 + // sourceItem: artworkContainer + // hideSource: true + // } + // property variant mask: ShaderEffectSource { + // format: ShaderEffectSource.RGBA8 + // sourceItem: maskRect + // hideSource: true + // } - fragmentShader: " - varying highp vec2 qt_TexCoord0; - uniform sampler2D source; - uniform sampler2D mask; - void main(void) - { - highp vec4 sourceColor = texture2D(source, qt_TexCoord0); - highp float alpha = texture2D(mask, vec2(qt_TexCoord0.y, qt_TexCoord0.x)).a; - sourceColor *= alpha; - gl_FragColor = sourceColor; - } - " - } + // fragmentShader: "/ui/shaders/colorizedimage.frag.qsb" + // } } } } diff --git a/nymea-app/ui/devicelistpages/PowerSocketsDeviceListPage.qml b/nymea-app/ui/devicelistpages/PowerSocketsDeviceListPage.qml index efa3a9d3..8177eba8 100644 --- a/nymea-app/ui/devicelistpages/PowerSocketsDeviceListPage.qml +++ b/nymea-app/ui/devicelistpages/PowerSocketsDeviceListPage.qml @@ -22,13 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material +import Nymea + import "../components" import "../delegates" -import QtQuick.Controls.Material 2.1 ThingsListPageBase { id: root diff --git a/nymea-app/ui/devicelistpages/SensorsDeviceListPage.qml b/nymea-app/ui/devicelistpages/SensorsDeviceListPage.qml index 914c90f7..d6c4fa35 100644 --- a/nymea-app/ui/devicelistpages/SensorsDeviceListPage.qml +++ b/nymea-app/ui/devicelistpages/SensorsDeviceListPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "qrc:/ui/components" import "qrc:/ui/delegates" diff --git a/nymea-app/ui/devicelistpages/ShutterDeviceListPage.qml b/nymea-app/ui/devicelistpages/ShutterDeviceListPage.qml index e4a06373..7952e21b 100644 --- a/nymea-app/ui/devicelistpages/ShutterDeviceListPage.qml +++ b/nymea-app/ui/devicelistpages/ShutterDeviceListPage.qml @@ -22,7 +22,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 +import QtQuick ClosablesThingsListPage { title: qsTr("Shutters") diff --git a/nymea-app/ui/devicelistpages/SmartMeterDeviceListPage.qml b/nymea-app/ui/devicelistpages/SmartMeterDeviceListPage.qml index 1bd8beeb..2775b1f1 100644 --- a/nymea-app/ui/devicelistpages/SmartMeterDeviceListPage.qml +++ b/nymea-app/ui/devicelistpages/SmartMeterDeviceListPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" ThingsListPageBase { diff --git a/nymea-app/ui/devicelistpages/ThingsListPageBase.qml b/nymea-app/ui/devicelistpages/ThingsListPageBase.qml index 7ea2941a..ad650e92 100644 --- a/nymea-app/ui/devicelistpages/ThingsListPageBase.qml +++ b/nymea-app/ui/devicelistpages/ThingsListPageBase.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea +import NymeaApp.Utils + import "../components" Page { diff --git a/nymea-app/ui/devicelistpages/WeatherDeviceListPage.qml b/nymea-app/ui/devicelistpages/WeatherDeviceListPage.qml index db5c11d2..35bdde75 100644 --- a/nymea-app/ui/devicelistpages/WeatherDeviceListPage.qml +++ b/nymea-app/ui/devicelistpages/WeatherDeviceListPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" import "../customviews" diff --git a/nymea-app/ui/devicepages/ActionLogPage.qml b/nymea-app/ui/devicepages/ActionLogPage.qml index 2dd0944c..69a273a8 100644 --- a/nymea-app/ui/devicepages/ActionLogPage.qml +++ b/nymea-app/ui/devicepages/ActionLogPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" import "../customviews" diff --git a/nymea-app/ui/devicepages/AwningThingPage.qml b/nymea-app/ui/devicepages/AwningThingPage.qml index c9c6bc21..ae864bb0 100644 --- a/nymea-app/ui/devicepages/AwningThingPage.qml +++ b/nymea-app/ui/devicepages/AwningThingPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtGraphicalEffects 1.0 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import Qt5Compat.GraphicalEffects +import QtQuick.Layouts +import Nymea + import "../components" import "../customviews" import "../utils" diff --git a/nymea-app/ui/devicepages/BarcodeScannerThingPage.qml b/nymea-app/ui/devicepages/BarcodeScannerThingPage.qml index aa88b86c..d33d61e9 100644 --- a/nymea-app/ui/devicepages/BarcodeScannerThingPage.qml +++ b/nymea-app/ui/devicepages/BarcodeScannerThingPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../customviews" diff --git a/nymea-app/ui/devicepages/BoolSensorDevicePage.qml b/nymea-app/ui/devicepages/BoolSensorDevicePage.qml index 403e51c8..59c1d14e 100644 --- a/nymea-app/ui/devicepages/BoolSensorDevicePage.qml +++ b/nymea-app/ui/devicepages/BoolSensorDevicePage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../customviews" diff --git a/nymea-app/ui/devicepages/ButtonThingPage.qml b/nymea-app/ui/devicepages/ButtonThingPage.qml index 06e266e9..48c333bb 100644 --- a/nymea-app/ui/devicepages/ButtonThingPage.qml +++ b/nymea-app/ui/devicepages/ButtonThingPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../customviews" diff --git a/nymea-app/ui/devicepages/CleaningRobotThingPage.qml b/nymea-app/ui/devicepages/CleaningRobotThingPage.qml index 1024d9c4..a4054f2d 100644 --- a/nymea-app/ui/devicepages/CleaningRobotThingPage.qml +++ b/nymea-app/ui/devicepages/CleaningRobotThingPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" import "../customviews" diff --git a/nymea-app/ui/devicepages/CoolingThingPage.qml b/nymea-app/ui/devicepages/CoolingThingPage.qml index 888dcc1a..289440d4 100644 --- a/nymea-app/ui/devicepages/CoolingThingPage.qml +++ b/nymea-app/ui/devicepages/CoolingThingPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import QtQuick.Controls.Material 2.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material +import Nymea + import "../components" import "../utils" diff --git a/nymea-app/ui/devicepages/DeviceBrowserPage.qml b/nymea-app/ui/devicepages/DeviceBrowserPage.qml index 26262da9..29360162 100644 --- a/nymea-app/ui/devicepages/DeviceBrowserPage.qml +++ b/nymea-app/ui/devicepages/DeviceBrowserPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../delegates" diff --git a/nymea-app/ui/devicepages/DeviceDetailsPage.qml b/nymea-app/ui/devicepages/DeviceDetailsPage.qml index 5874ffe0..ea09c028 100644 --- a/nymea-app/ui/devicepages/DeviceDetailsPage.qml +++ b/nymea-app/ui/devicepages/DeviceDetailsPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Layouts 1.1 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material +import Nymea + import "../components" import "../delegates" diff --git a/nymea-app/ui/devicepages/DeviceLogPage.qml b/nymea-app/ui/devicepages/DeviceLogPage.qml index e9c8de9b..335be54a 100644 --- a/nymea-app/ui/devicepages/DeviceLogPage.qml +++ b/nymea-app/ui/devicepages/DeviceLogPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" import "../customviews" diff --git a/nymea-app/ui/devicepages/DoorbellDevicePage.qml b/nymea-app/ui/devicepages/DoorbellDevicePage.qml index 4526f25f..3830b69f 100644 --- a/nymea-app/ui/devicepages/DoorbellDevicePage.qml +++ b/nymea-app/ui/devicepages/DoorbellDevicePage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../customviews" diff --git a/nymea-app/ui/devicepages/EvChargerThingPage.qml b/nymea-app/ui/devicepages/EvChargerThingPage.qml index 331ccdd3..88795c24 100644 --- a/nymea-app/ui/devicepages/EvChargerThingPage.qml +++ b/nymea-app/ui/devicepages/EvChargerThingPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../utils" diff --git a/nymea-app/ui/devicepages/EventLogPage.qml b/nymea-app/ui/devicepages/EventLogPage.qml index 349acba8..535707a7 100644 --- a/nymea-app/ui/devicepages/EventLogPage.qml +++ b/nymea-app/ui/devicepages/EventLogPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" import "../customviews" diff --git a/nymea-app/ui/devicepages/FingerprintReaderDevicePage.qml b/nymea-app/ui/devicepages/FingerprintReaderDevicePage.qml index 7b635fce..fa689cd5 100644 --- a/nymea-app/ui/devicepages/FingerprintReaderDevicePage.qml +++ b/nymea-app/ui/devicepages/FingerprintReaderDevicePage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../customviews" diff --git a/nymea-app/ui/devicepages/GarageThingPage.qml b/nymea-app/ui/devicepages/GarageThingPage.qml index e7049b26..98170d2f 100644 --- a/nymea-app/ui/devicepages/GarageThingPage.qml +++ b/nymea-app/ui/devicepages/GarageThingPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" import "../customviews" diff --git a/nymea-app/ui/devicepages/GenericThingPage.qml b/nymea-app/ui/devicepages/GenericThingPage.qml index f285b103..a2a01106 100644 --- a/nymea-app/ui/devicepages/GenericThingPage.qml +++ b/nymea-app/ui/devicepages/GenericThingPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" import "../delegates" diff --git a/nymea-app/ui/devicepages/HeatingDevicePage.qml b/nymea-app/ui/devicepages/HeatingDevicePage.qml index 4ce1dabb..16da1865 100644 --- a/nymea-app/ui/devicepages/HeatingDevicePage.qml +++ b/nymea-app/ui/devicepages/HeatingDevicePage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import QtQuick.Controls.Material 2.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material +import Nymea + import "../components" import "../utils" diff --git a/nymea-app/ui/devicepages/InputTriggerDevicePage.qml b/nymea-app/ui/devicepages/InputTriggerDevicePage.qml index cbc5c3c8..0e519e66 100644 --- a/nymea-app/ui/devicepages/InputTriggerDevicePage.qml +++ b/nymea-app/ui/devicepages/InputTriggerDevicePage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../customviews" diff --git a/nymea-app/ui/devicepages/IrrigationDevicePage.qml b/nymea-app/ui/devicepages/IrrigationDevicePage.qml index 6f6634ce..050ad844 100644 --- a/nymea-app/ui/devicepages/IrrigationDevicePage.qml +++ b/nymea-app/ui/devicepages/IrrigationDevicePage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import QtQuick.Controls.Material 2.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material +import Nymea + import "../components" import "../utils" diff --git a/nymea-app/ui/devicepages/LightThingPage.qml b/nymea-app/ui/devicepages/LightThingPage.qml index a24cfc79..e453425f 100644 --- a/nymea-app/ui/devicepages/LightThingPage.qml +++ b/nymea-app/ui/devicepages/LightThingPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.3 -import QtQuick.Controls.Material 2.1 -import Nymea 1.0 -import QtGraphicalEffects 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material +import Qt5Compat.GraphicalEffects +import Nymea + import "../components" import "../utils" @@ -180,24 +181,7 @@ ThingPageBase { property real threshold: 0.1 property real brightness: 1 - (actionQueue.pendingValue || brightnessState.value) / 100 - fragmentShader: " - varying highp vec2 qt_TexCoord0; - uniform sampler2D source; - uniform highp vec4 outColor; - uniform highp vec4 inColor; - uniform lowp float threshold; - uniform lowp float qt_Opacity; - uniform lowp float brightness; - void main() { - bool isOn = qt_TexCoord0.y > brightness; - lowp vec4 sourceColor = texture2D(source, qt_TexCoord0); - if (isOn) { - gl_FragColor = mix(vec4(outColor.rgb, 1.0) * sourceColor.a, sourceColor, step(threshold, distance(sourceColor.rgb / sourceColor.a, inColor.rgb))) * qt_Opacity; - } else { - gl_FragColor = sourceColor; - } - }" - + fragmentShader: "/ui/shaders/brightnesscircle.frag.qsb" } MouseArea { diff --git a/nymea-app/ui/devicepages/MediaThingPage.qml b/nymea-app/ui/devicepages/MediaThingPage.qml index ff0146f6..64d9f50c 100644 --- a/nymea-app/ui/devicepages/MediaThingPage.qml +++ b/nymea-app/ui/devicepages/MediaThingPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import QtGraphicalEffects 1.0 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Qt5Compat.GraphicalEffects +import Nymea + import "../components" import "../customviews" import "../delegates" diff --git a/nymea-app/ui/devicepages/NotificationsThingPage.qml b/nymea-app/ui/devicepages/NotificationsThingPage.qml index 78287409..c948c648 100644 --- a/nymea-app/ui/devicepages/NotificationsThingPage.qml +++ b/nymea-app/ui/devicepages/NotificationsThingPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../customviews" diff --git a/nymea-app/ui/devicepages/PowersocketDevicePage.qml b/nymea-app/ui/devicepages/PowersocketDevicePage.qml index 84b63ae8..921177a8 100644 --- a/nymea-app/ui/devicepages/PowersocketDevicePage.qml +++ b/nymea-app/ui/devicepages/PowersocketDevicePage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import QtGraphicalEffects 1.0 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Qt5Compat.GraphicalEffects +import Nymea + import "../components" import "../utils" diff --git a/nymea-app/ui/devicepages/SensorDevicePage.qml b/nymea-app/ui/devicepages/SensorDevicePage.qml index caaac20e..051e1485 100644 --- a/nymea-app/ui/devicepages/SensorDevicePage.qml +++ b/nymea-app/ui/devicepages/SensorDevicePage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import QtGraphicalEffects 1.0 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Qt5Compat.GraphicalEffects +import Nymea +import NymeaApp.Utils + import "../components" import "../customviews" diff --git a/nymea-app/ui/devicepages/ShutterDevicePage.qml b/nymea-app/ui/devicepages/ShutterDevicePage.qml index 0919c237..dc48a5fe 100644 --- a/nymea-app/ui/devicepages/ShutterDevicePage.qml +++ b/nymea-app/ui/devicepages/ShutterDevicePage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import QtGraphicalEffects 1.0 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Qt5Compat.GraphicalEffects +import Nymea + import "../components" import "../customviews" import "../utils" diff --git a/nymea-app/ui/devicepages/SmartMeterDevicePage.qml b/nymea-app/ui/devicepages/SmartMeterDevicePage.qml index a67440ab..ad0be921 100644 --- a/nymea-app/ui/devicepages/SmartMeterDevicePage.qml +++ b/nymea-app/ui/devicepages/SmartMeterDevicePage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import QtGraphicalEffects 1.0 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Qt5Compat.GraphicalEffects +import Nymea + import "../components" import "../customviews" diff --git a/nymea-app/ui/devicepages/StateLogPage.qml b/nymea-app/ui/devicepages/StateLogPage.qml index 621dbcef..6126d135 100644 --- a/nymea-app/ui/devicepages/StateLogPage.qml +++ b/nymea-app/ui/devicepages/StateLogPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" import "../customviews" diff --git a/nymea-app/ui/devicepages/ThermostatDevicePage.qml b/nymea-app/ui/devicepages/ThermostatDevicePage.qml index 6e660e28..65174c51 100644 --- a/nymea-app/ui/devicepages/ThermostatDevicePage.qml +++ b/nymea-app/ui/devicepages/ThermostatDevicePage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" import "../customviews" import "../utils" diff --git a/nymea-app/ui/devicepages/ThingLogPage.qml b/nymea-app/ui/devicepages/ThingLogPage.qml index f01c9661..c3e5830b 100644 --- a/nymea-app/ui/devicepages/ThingLogPage.qml +++ b/nymea-app/ui/devicepages/ThingLogPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" import "../customviews" diff --git a/nymea-app/ui/devicepages/ThingPageBase.qml b/nymea-app/ui/devicepages/ThingPageBase.qml index 019ae4ea..9cefae4a 100644 --- a/nymea-app/ui/devicepages/ThingPageBase.qml +++ b/nymea-app/ui/devicepages/ThingPageBase.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" Page { diff --git a/nymea-app/ui/devicepages/ThingStatusPage.qml b/nymea-app/ui/devicepages/ThingStatusPage.qml index 6621dc32..ddd03cae 100644 --- a/nymea-app/ui/devicepages/ThingStatusPage.qml +++ b/nymea-app/ui/devicepages/ThingStatusPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" import "../customviews" diff --git a/nymea-app/ui/devicepages/VentilationThingPage.qml b/nymea-app/ui/devicepages/VentilationThingPage.qml index 360bb07b..70bbcc1e 100644 --- a/nymea-app/ui/devicepages/VentilationThingPage.qml +++ b/nymea-app/ui/devicepages/VentilationThingPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../utils" diff --git a/nymea-app/ui/devicepages/WeatherDevicePage.qml b/nymea-app/ui/devicepages/WeatherDevicePage.qml index 5cfe6e36..49fdad9d 100644 --- a/nymea-app/ui/devicepages/WeatherDevicePage.qml +++ b/nymea-app/ui/devicepages/WeatherDevicePage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../customviews" diff --git a/nymea-app/ui/experiences/heating/Main.qml b/nymea-app/ui/experiences/heating/Main.qml index a737fa31..3e985d28 100644 --- a/nymea-app/ui/experiences/heating/Main.qml +++ b/nymea-app/ui/experiences/heating/Main.qml @@ -22,13 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material +import Qt5Compat.GraphicalEffects +import Nymea + import "qrc:/ui/components" -import Nymea 1.0 -import QtGraphicalEffects 1.0 Item { id: root diff --git a/nymea-app/ui/grouping/GroupInterfacesPage.qml b/nymea-app/ui/grouping/GroupInterfacesPage.qml index 4ca7bc7d..33de5737 100644 --- a/nymea-app/ui/grouping/GroupInterfacesPage.qml +++ b/nymea-app/ui/grouping/GroupInterfacesPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" import "../delegates" import "../mainviews" diff --git a/nymea-app/ui/grouping/GroupThingsPage.qml b/nymea-app/ui/grouping/GroupThingsPage.qml index e528babf..57c06445 100644 --- a/nymea-app/ui/grouping/GroupThingsPage.qml +++ b/nymea-app/ui/grouping/GroupThingsPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea +import NymeaApp.Utils + import "../components" import "../delegates" diff --git a/nymea-app/ui/magic/CalendarItemDelegate.qml b/nymea-app/ui/magic/CalendarItemDelegate.qml index ca90f6c7..e55520f7 100644 --- a/nymea-app/ui/magic/CalendarItemDelegate.qml +++ b/nymea-app/ui/magic/CalendarItemDelegate.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" NymeaSwipeDelegate { diff --git a/nymea-app/ui/magic/ComposeEventDescriptorPage.qml b/nymea-app/ui/magic/ComposeEventDescriptorPage.qml index 18896b2c..0e20052f 100644 --- a/nymea-app/ui/magic/ComposeEventDescriptorPage.qml +++ b/nymea-app/ui/magic/ComposeEventDescriptorPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.6 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea + import "../components" -import Nymea 1.0 Page { id: root diff --git a/nymea-app/ui/magic/EditCalendarItemPage.qml b/nymea-app/ui/magic/EditCalendarItemPage.qml index b2603148..820d60bc 100644 --- a/nymea-app/ui/magic/EditCalendarItemPage.qml +++ b/nymea-app/ui/magic/EditCalendarItemPage.qml @@ -22,12 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import Qt.labs.calendar 1.0 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" -import Nymea 1.0 Page { id: root @@ -218,7 +218,7 @@ Page { } return ret; } - onActivated: { + onActivated: (index) => { var date = root.calendarItem.dateTime date.setDate(index) root.calendarItem.dateTime = date; diff --git a/nymea-app/ui/magic/EditRulePage.qml b/nymea-app/ui/magic/EditRulePage.qml index e99cb61d..0763db08 100644 --- a/nymea-app/ui/magic/EditRulePage.qml +++ b/nymea-app/ui/magic/EditRulePage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Layouts 1.3 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea + import "../components" -import Nymea 1.0 Page { id: root diff --git a/nymea-app/ui/magic/EditStateEvaluatorPage.qml b/nymea-app/ui/magic/EditStateEvaluatorPage.qml index 3a5c6316..f4505500 100644 --- a/nymea-app/ui/magic/EditStateEvaluatorPage.qml +++ b/nymea-app/ui/magic/EditStateEvaluatorPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" Page { diff --git a/nymea-app/ui/magic/EditTimeEventItemPage.qml b/nymea-app/ui/magic/EditTimeEventItemPage.qml index ed2e4b7d..50c32e86 100644 --- a/nymea-app/ui/magic/EditTimeEventItemPage.qml +++ b/nymea-app/ui/magic/EditTimeEventItemPage.qml @@ -22,12 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import Qt.labs.calendar 1.0 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" -import Nymea 1.0 Page { id: root @@ -322,5 +322,4 @@ Page { } } } - } diff --git a/nymea-app/ui/magic/EventDescriptorDelegate.qml b/nymea-app/ui/magic/EventDescriptorDelegate.qml index ffc975c8..3a378fcd 100644 --- a/nymea-app/ui/magic/EventDescriptorDelegate.qml +++ b/nymea-app/ui/magic/EventDescriptorDelegate.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" NymeaSwipeDelegate { diff --git a/nymea-app/ui/magic/NewMagicPage.qml b/nymea-app/ui/magic/NewMagicPage.qml index 71da3a1a..3cb89f69 100644 --- a/nymea-app/ui/magic/NewMagicPage.qml +++ b/nymea-app/ui/magic/NewMagicPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" Page { diff --git a/nymea-app/ui/magic/NewScenePage.qml b/nymea-app/ui/magic/NewScenePage.qml index acd885c3..db174766 100644 --- a/nymea-app/ui/magic/NewScenePage.qml +++ b/nymea-app/ui/magic/NewScenePage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" Page { diff --git a/nymea-app/ui/magic/NewThingMagicPage.qml b/nymea-app/ui/magic/NewThingMagicPage.qml index df217879..c40a4cc2 100644 --- a/nymea-app/ui/magic/NewThingMagicPage.qml +++ b/nymea-app/ui/magic/NewThingMagicPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" Page { diff --git a/nymea-app/ui/magic/RuleActionDelegate.qml b/nymea-app/ui/magic/RuleActionDelegate.qml index 2ab09c94..6a58ede6 100644 --- a/nymea-app/ui/magic/RuleActionDelegate.qml +++ b/nymea-app/ui/magic/RuleActionDelegate.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" NymeaSwipeDelegate { diff --git a/nymea-app/ui/magic/ScriptEditor.qml b/nymea-app/ui/magic/ScriptEditor.qml index 71b8d38b..e14341d5 100644 --- a/nymea-app/ui/magic/ScriptEditor.qml +++ b/nymea-app/ui/magic/ScriptEditor.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import Nymea 1.0 -import QtQuick.Layouts 1.2 -import QtQuick.Controls.Material 2.1 -import Qt.labs.settings 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material +import QtCore +import Nymea + import "../components" import "scripting" @@ -40,7 +41,7 @@ Page { if (scriptId !== undefined) {; d.callId = engine.scriptManager.fetchScript(scriptId); } else { - scriptEdit.text = "import QtQuick 2.0\nimport nymea 1.0\n\nItem {\n \n}\n" + scriptEdit.text = "import QtQuick\nimport nymea 1.0\n\nItem {\n \n}\n" } if ((Qt.platform.os == "android" || Qt.platform.os == "ios") && !editorSettings.popupWasShown) { @@ -167,8 +168,8 @@ Page { } } - onFetchScriptReply: { - if (id == d.callId && status == ScriptManager.ScriptErrorNoError) { + onFetchScriptReply: (id, status, content) => { + if (id === d.callId && status === ScriptManager.ScriptErrorNoError) { d.callId = -1; d.oldContent = content; diff --git a/nymea-app/ui/magic/ScriptsPage.qml b/nymea-app/ui/magic/ScriptsPage.qml index 0d823a5e..52989d0b 100644 --- a/nymea-app/ui/magic/ScriptsPage.qml +++ b/nymea-app/ui/magic/ScriptsPage.qml @@ -22,9 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import Nymea 1.0 -import QtQuick.Controls 2.2 +import QtQuick +import QtQuick.Controls +import Nymea + import "../components" Page { diff --git a/nymea-app/ui/magic/SelectBrowserItemActionPage.qml b/nymea-app/ui/magic/SelectBrowserItemActionPage.qml index 7cb71f7b..e74363ff 100644 --- a/nymea-app/ui/magic/SelectBrowserItemActionPage.qml +++ b/nymea-app/ui/magic/SelectBrowserItemActionPage.qml @@ -22,9 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.4 -import QtQuick.Controls 2.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import Nymea + import "../components" import "../delegates" diff --git a/nymea-app/ui/magic/SelectEventDescriptorPage.qml b/nymea-app/ui/magic/SelectEventDescriptorPage.qml index d3233cdb..8c949a38 100644 --- a/nymea-app/ui/magic/SelectEventDescriptorPage.qml +++ b/nymea-app/ui/magic/SelectEventDescriptorPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.4 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" -import Nymea 1.0 Page { id: root diff --git a/nymea-app/ui/magic/SelectEventDescriptorParamsPage.qml b/nymea-app/ui/magic/SelectEventDescriptorParamsPage.qml index d39a2cbf..770765ac 100644 --- a/nymea-app/ui/magic/SelectEventDescriptorParamsPage.qml +++ b/nymea-app/ui/magic/SelectEventDescriptorParamsPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../delegates" -import Nymea 1.0 Page { id: root diff --git a/nymea-app/ui/magic/SelectRuleActionPage.qml b/nymea-app/ui/magic/SelectRuleActionPage.qml index d83ab993..86d48df9 100644 --- a/nymea-app/ui/magic/SelectRuleActionPage.qml +++ b/nymea-app/ui/magic/SelectRuleActionPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.4 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Controls +import Nymea + import "../components" -import Nymea 1.0 Page { id: root diff --git a/nymea-app/ui/magic/SelectRuleActionParamsPage.qml b/nymea-app/ui/magic/SelectRuleActionParamsPage.qml index 897a502b..3b96acfd 100644 --- a/nymea-app/ui/magic/SelectRuleActionParamsPage.qml +++ b/nymea-app/ui/magic/SelectRuleActionParamsPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../delegates" -import Nymea 1.0 Page { id: root diff --git a/nymea-app/ui/magic/SelectStateDescriptorPage.qml b/nymea-app/ui/magic/SelectStateDescriptorPage.qml index 5334045c..29d4a2e1 100644 --- a/nymea-app/ui/magic/SelectStateDescriptorPage.qml +++ b/nymea-app/ui/magic/SelectStateDescriptorPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.4 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Controls +import Nymea + import "../components" -import Nymea 1.0 Page { id: root diff --git a/nymea-app/ui/magic/SelectStateDescriptorParamsPage.qml b/nymea-app/ui/magic/SelectStateDescriptorParamsPage.qml index 00f012cf..9739ce21 100644 --- a/nymea-app/ui/magic/SelectStateDescriptorParamsPage.qml +++ b/nymea-app/ui/magic/SelectStateDescriptorParamsPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../delegates" -import Nymea 1.0 Page { id: root diff --git a/nymea-app/ui/magic/SelectStatePage.qml b/nymea-app/ui/magic/SelectStatePage.qml index d8ff2d6c..5b215cb9 100644 --- a/nymea-app/ui/magic/SelectStatePage.qml +++ b/nymea-app/ui/magic/SelectStatePage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../delegates" -import Nymea 1.0 Page { id: root diff --git a/nymea-app/ui/magic/SelectThingPage.qml b/nymea-app/ui/magic/SelectThingPage.qml index 9cee9e7e..17b31954 100644 --- a/nymea-app/ui/magic/SelectThingPage.qml +++ b/nymea-app/ui/magic/SelectThingPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.6 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea + import "../components" import "../delegates" -import Nymea 1.0 Page { id: root diff --git a/nymea-app/ui/magic/SimpleStateEvaluatorDelegate.qml b/nymea-app/ui/magic/SimpleStateEvaluatorDelegate.qml index e5ae3726..1780f327 100644 --- a/nymea-app/ui/magic/SimpleStateEvaluatorDelegate.qml +++ b/nymea-app/ui/magic/SimpleStateEvaluatorDelegate.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" SwipeDelegate { diff --git a/nymea-app/ui/magic/StateEvaluatorDelegate.qml b/nymea-app/ui/magic/StateEvaluatorDelegate.qml index 7276e462..62128306 100644 --- a/nymea-app/ui/magic/StateEvaluatorDelegate.qml +++ b/nymea-app/ui/magic/StateEvaluatorDelegate.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" ItemDelegate { @@ -105,8 +106,8 @@ ItemDelegate { model: [qsTr("and all of those"), qsTr("or any of those")] currentIndex: root.stateEvaluator && root.stateEvaluator.stateOperator === StateEvaluator.StateOperatorAnd ? 0 : 1 visible: root.stateEvaluator && root.stateEvaluator.childEvaluators.count > 0 - onActivated: { - root.stateEvaluator.stateOperator = index == 0 ? StateEvaluator.StateOperatorAnd : StateEvaluator.StateOperatorOr + onActivated: (index) => { + root.stateEvaluator.stateOperator = index === 0 ? StateEvaluator.StateOperatorAnd : StateEvaluator.StateOperatorOr } } diff --git a/nymea-app/ui/magic/ThingRulesPage.qml b/nymea-app/ui/magic/ThingRulesPage.qml index ac2bbb1b..4de8d6fb 100644 --- a/nymea-app/ui/magic/ThingRulesPage.qml +++ b/nymea-app/ui/magic/ThingRulesPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" -import Nymea 1.0 Page { id: root diff --git a/nymea-app/ui/magic/TimeEventDelegate.qml b/nymea-app/ui/magic/TimeEventDelegate.qml index b3ac730c..78806a5c 100644 --- a/nymea-app/ui/magic/TimeEventDelegate.qml +++ b/nymea-app/ui/magic/TimeEventDelegate.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" NymeaSwipeDelegate{ diff --git a/nymea-app/ui/magic/WriteNfcTagPage.qml b/nymea-app/ui/magic/WriteNfcTagPage.qml index a7bcc52c..57ebd936 100644 --- a/nymea-app/ui/magic/WriteNfcTagPage.qml +++ b/nymea-app/ui/magic/WriteNfcTagPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" Page { diff --git a/nymea-app/ui/magic/scripting/CompletionBox.qml b/nymea-app/ui/magic/scripting/CompletionBox.qml index 80b39b7c..1b33a756 100644 --- a/nymea-app/ui/magic/scripting/CompletionBox.qml +++ b/nymea-app/ui/magic/scripting/CompletionBox.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.2 -import QtQuick.Controls 2.2 -import Nymea 1.0 -import QtQuick.Layouts 1.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../../components" Rectangle { diff --git a/nymea-app/ui/magic/scripting/EditorPane.qml b/nymea-app/ui/magic/scripting/EditorPane.qml index a4170175..e32cd5dd 100644 --- a/nymea-app/ui/magic/scripting/EditorPane.qml +++ b/nymea-app/ui/magic/scripting/EditorPane.qml @@ -22,11 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.2 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.1 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts import "../../components" -import Nymea 1.0 +import Nymea Item { id: pane diff --git a/nymea-app/ui/magic/scripting/LineNumbers.qml b/nymea-app/ui/magic/scripting/LineNumbers.qml index 93a3a06d..699f159b 100644 --- a/nymea-app/ui/magic/scripting/LineNumbers.qml +++ b/nymea-app/ui/magic/scripting/LineNumbers.qml @@ -22,9 +22,9 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.4 -import QtQuick.Controls 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import Nymea Rectangle { id: root diff --git a/nymea-app/ui/mainviews/AirConditioningView.qml b/nymea-app/ui/mainviews/AirConditioningView.qml index b9177b58..d64ee169 100644 --- a/nymea-app/ui/mainviews/AirConditioningView.qml +++ b/nymea-app/ui/mainviews/AirConditioningView.qml @@ -22,15 +22,16 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtGraphicalEffects 1.0 -import QtCharts 2.2 -import Nymea 1.0 -import NymeaApp.Utils 1.0 -import Nymea.AirConditioning 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Qt5Compat.GraphicalEffects +import QtCharts +import Nymea +import NymeaApp.Utils +import Nymea.AirConditioning + import "qrc:/ui/components" import "qrc:/ui/delegates" import "airconditioning" diff --git a/nymea-app/ui/mainviews/DashboardView.qml b/nymea-app/ui/mainviews/DashboardView.qml index 27a6cfc0..60e6d0e7 100644 --- a/nymea-app/ui/mainviews/DashboardView.qml +++ b/nymea-app/ui/mainviews/DashboardView.qml @@ -22,13 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtCharts 2.2 -import Nymea 1.0 -import Qt.labs.settings 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts +import Nymea +import QtCore import "../components" import "dashboard" diff --git a/nymea-app/ui/mainviews/EnergyView.qml b/nymea-app/ui/mainviews/EnergyView.qml index 327fb800..7978797d 100644 --- a/nymea-app/ui/mainviews/EnergyView.qml +++ b/nymea-app/ui/mainviews/EnergyView.qml @@ -22,13 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts import Qt5Compat.GraphicalEffects -import QtCharts 2.2 -import Nymea 1.0 +import QtCharts +import Nymea + import "../components" import "../delegates" import "energy" diff --git a/nymea-app/ui/mainviews/FavoritesView.qml b/nymea-app/ui/mainviews/FavoritesView.qml index 50d105d3..ca645b55 100644 --- a/nymea-app/ui/mainviews/FavoritesView.qml +++ b/nymea-app/ui/mainviews/FavoritesView.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import QtQuick.Controls.Material 2.2 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material +import Nymea +import NymeaApp.Utils + import "../components" import "../delegates" diff --git a/nymea-app/ui/mainviews/GaragesView.qml b/nymea-app/ui/mainviews/GaragesView.qml index d4cd9d63..2975f9da 100644 --- a/nymea-app/ui/mainviews/GaragesView.qml +++ b/nymea-app/ui/mainviews/GaragesView.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea + import "../components" import "../customviews" -import Nymea 1.0 MainViewBase { id: root diff --git a/nymea-app/ui/mainviews/GroupsView.qml b/nymea-app/ui/mainviews/GroupsView.qml index 8b701289..9651f593 100644 --- a/nymea-app/ui/mainviews/GroupsView.qml +++ b/nymea-app/ui/mainviews/GroupsView.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 -import QtQuick.Controls.Material 2.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material +import Nymea + import "../components" MainViewBase { diff --git a/nymea-app/ui/mainviews/MediaView.qml b/nymea-app/ui/mainviews/MediaView.qml index a507c1ed..112deeb7 100644 --- a/nymea-app/ui/mainviews/MediaView.qml +++ b/nymea-app/ui/mainviews/MediaView.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtCharts 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts +import Nymea + import "../components" import "../delegates" diff --git a/nymea-app/ui/mainviews/ScenesView.qml b/nymea-app/ui/mainviews/ScenesView.qml index 8e746b4b..3e3656e3 100644 --- a/nymea-app/ui/mainviews/ScenesView.qml +++ b/nymea-app/ui/mainviews/ScenesView.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 -import QtQuick.Controls.Material 2.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea +import QtQuick.Controls.Material + import "../components" MainViewBase { diff --git a/nymea-app/ui/mainviews/ThingsView.qml b/nymea-app/ui/mainviews/ThingsView.qml index 26924e25..0f8cb909 100644 --- a/nymea-app/ui/mainviews/ThingsView.qml +++ b/nymea-app/ui/mainviews/ThingsView.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" import "../delegates" diff --git a/nymea-app/ui/mainviews/airconditioning/ACChartsPage.qml b/nymea-app/ui/mainviews/airconditioning/ACChartsPage.qml index ee4a9f25..94d410b7 100644 --- a/nymea-app/ui/mainviews/airconditioning/ACChartsPage.qml +++ b/nymea-app/ui/mainviews/airconditioning/ACChartsPage.qml @@ -22,14 +22,15 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.1 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtCharts +import Nymea +import Nymea.AirConditioning + import "qrc:/ui/components" import "qrc:/ui/customviews" -import Nymea 1.0 -import Nymea.AirConditioning 1.0 -import QtCharts 2.3 Page { id: root diff --git a/nymea-app/ui/mainviews/airconditioning/ACSettingsPage.qml b/nymea-app/ui/mainviews/airconditioning/ACSettingsPage.qml index 80f5b939..6f318c0e 100644 --- a/nymea-app/ui/mainviews/airconditioning/ACSettingsPage.qml +++ b/nymea-app/ui/mainviews/airconditioning/ACSettingsPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import Nymea 1.0 -import Nymea.AirConditioning 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea +import Nymea.AirConditioning + import "qrc:/ui/components" import "qrc:/ui/delegates" diff --git a/nymea-app/ui/mainviews/airconditioning/BigZoneStatusIcons.qml b/nymea-app/ui/mainviews/airconditioning/BigZoneStatusIcons.qml index 9a2d2589..562c45b1 100644 --- a/nymea-app/ui/mainviews/airconditioning/BigZoneStatusIcons.qml +++ b/nymea-app/ui/mainviews/airconditioning/BigZoneStatusIcons.qml @@ -22,13 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.3 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea +import NymeaApp.Utils +import Nymea.AirConditioning + import "qrc:/ui/components" -import Nymea 1.0 -import NymeaApp.Utils 1.0 -import Nymea.AirConditioning 1.0 Item { id: root diff --git a/nymea-app/ui/mainviews/airconditioning/EditZonePage.qml b/nymea-app/ui/mainviews/airconditioning/EditZonePage.qml index 7ea0b67b..190ff808 100644 --- a/nymea-app/ui/mainviews/airconditioning/EditZonePage.qml +++ b/nymea-app/ui/mainviews/airconditioning/EditZonePage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import Nymea 1.0 -import Nymea.AirConditioning 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea +import Nymea.AirConditioning + import "qrc:/ui/components" import "qrc:/ui/delegates" diff --git a/nymea-app/ui/mainviews/airconditioning/EditZoneThingsPage.qml b/nymea-app/ui/mainviews/airconditioning/EditZoneThingsPage.qml index 4947aadb..0bde9b39 100644 --- a/nymea-app/ui/mainviews/airconditioning/EditZoneThingsPage.qml +++ b/nymea-app/ui/mainviews/airconditioning/EditZoneThingsPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import Nymea 1.0 -import Nymea.AirConditioning 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea +import Nymea.AirConditioning + import "qrc:/ui/components" import "qrc:/ui/delegates" diff --git a/nymea-app/ui/mainviews/airconditioning/LegendDelegate.qml b/nymea-app/ui/mainviews/airconditioning/LegendDelegate.qml index 63290e3f..2b324539 100644 --- a/nymea-app/ui/mainviews/airconditioning/LegendDelegate.qml +++ b/nymea-app/ui/mainviews/airconditioning/LegendDelegate.qml @@ -22,14 +22,15 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.1 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtCharts +import Nymea +import Nymea.AirConditioning + import "qrc:/ui/components" import "qrc:/ui/customviews" -import Nymea 1.0 -import Nymea.AirConditioning 1.0 -import QtCharts 2.3 Item { id: root diff --git a/nymea-app/ui/mainviews/airconditioning/TemperatureScheduleEditor.qml b/nymea-app/ui/mainviews/airconditioning/TemperatureScheduleEditor.qml index f8cfce77..3991fb2a 100644 --- a/nymea-app/ui/mainviews/airconditioning/TemperatureScheduleEditor.qml +++ b/nymea-app/ui/mainviews/airconditioning/TemperatureScheduleEditor.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.1 -import Nymea 1.0 -import Nymea.AirConditioning 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea +import Nymea.AirConditioning + import "qrc:/ui/components" ColumnLayout { diff --git a/nymea-app/ui/mainviews/airconditioning/TimeOverrideDialog.qml b/nymea-app/ui/mainviews/airconditioning/TimeOverrideDialog.qml index 27c6088b..c845b4fb 100644 --- a/nymea-app/ui/mainviews/airconditioning/TimeOverrideDialog.qml +++ b/nymea-app/ui/mainviews/airconditioning/TimeOverrideDialog.qml @@ -22,15 +22,16 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.1 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea +import NymeaApp.Utils +import Nymea.AirConditioning + import "qrc:/ui/components" import "qrc:/ui/customviews" import "qrc:/ui/delegates" -import Nymea 1.0 -import NymeaApp.Utils 1.0 -import Nymea.AirConditioning 1.0 NymeaDialog { id: root diff --git a/nymea-app/ui/mainviews/airconditioning/TimeSchedulePage.qml b/nymea-app/ui/mainviews/airconditioning/TimeSchedulePage.qml index 7306b0a8..4a6f3a4a 100644 --- a/nymea-app/ui/mainviews/airconditioning/TimeSchedulePage.qml +++ b/nymea-app/ui/mainviews/airconditioning/TimeSchedulePage.qml @@ -22,13 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.1 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea +import Nymea.AirConditioning + import "qrc:/ui/components" import "qrc:/ui/customviews" -import Nymea 1.0 -import Nymea.AirConditioning 1.0 Page { id: root diff --git a/nymea-app/ui/mainviews/airconditioning/TooltipDelegate.qml b/nymea-app/ui/mainviews/airconditioning/TooltipDelegate.qml index 0322a77d..e2b202cf 100644 --- a/nymea-app/ui/mainviews/airconditioning/TooltipDelegate.qml +++ b/nymea-app/ui/mainviews/airconditioning/TooltipDelegate.qml @@ -22,14 +22,15 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.1 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtCharts +import Nymea +import Nymea.AirConditioning + import "qrc:/ui/components" import "qrc:/ui/customviews" -import Nymea 1.0 -import Nymea.AirConditioning 1.0 -import QtCharts 2.3 NymeaToolTip { id: root diff --git a/nymea-app/ui/mainviews/airconditioning/ZoneInfoWrapper.qml b/nymea-app/ui/mainviews/airconditioning/ZoneInfoWrapper.qml index f4a19ef7..8f50e199 100644 --- a/nymea-app/ui/mainviews/airconditioning/ZoneInfoWrapper.qml +++ b/nymea-app/ui/mainviews/airconditioning/ZoneInfoWrapper.qml @@ -22,14 +22,15 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtGraphicalEffects 1.0 -import QtCharts 2.2 -import Nymea 1.0 -import Nymea.AirConditioning 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Qt5Compat.GraphicalEffects +import QtCharts +import Nymea +import Nymea.AirConditioning + import "qrc:/ui/components" import "qrc:/ui/delegates" diff --git a/nymea-app/ui/mainviews/airconditioning/ZonePage.qml b/nymea-app/ui/mainviews/airconditioning/ZonePage.qml index e0e34ada..61838056 100644 --- a/nymea-app/ui/mainviews/airconditioning/ZonePage.qml +++ b/nymea-app/ui/mainviews/airconditioning/ZonePage.qml @@ -22,13 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.1 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea +import Nymea.AirConditioning + import "qrc:/ui/components" import "qrc:/ui/customviews" -import Nymea 1.0 -import Nymea.AirConditioning 1.0 Page { id: root diff --git a/nymea-app/ui/mainviews/airconditioning/ZoneStatusIcons.qml b/nymea-app/ui/mainviews/airconditioning/ZoneStatusIcons.qml index 6e9dc1a5..aa0d19f6 100644 --- a/nymea-app/ui/mainviews/airconditioning/ZoneStatusIcons.qml +++ b/nymea-app/ui/mainviews/airconditioning/ZoneStatusIcons.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Layouts 1.2 +import QtQuick +import QtQuick.Layouts +import Nymea +import Nymea.AirConditioning + import "qrc:/ui/components" -import Nymea 1.0 -import Nymea.AirConditioning 1.0 RowLayout { id: root diff --git a/nymea-app/ui/mainviews/airconditioning/ZoneView.qml b/nymea-app/ui/mainviews/airconditioning/ZoneView.qml index 74513bc9..3b7d37d9 100644 --- a/nymea-app/ui/mainviews/airconditioning/ZoneView.qml +++ b/nymea-app/ui/mainviews/airconditioning/ZoneView.qml @@ -22,15 +22,16 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.1 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea +import NymeaApp.Utils +import Nymea.AirConditioning + import "qrc:/ui/components" import "qrc:/ui/customviews" import "qrc:/ui/delegates" -import Nymea 1.0 -import NymeaApp.Utils 1.0 -import Nymea.AirConditioning 1.0 Item { id: root diff --git a/nymea-app/ui/mainviews/airconditioning/ZonesView.qml b/nymea-app/ui/mainviews/airconditioning/ZonesView.qml index 56a41800..dfe30184 100644 --- a/nymea-app/ui/mainviews/airconditioning/ZonesView.qml +++ b/nymea-app/ui/mainviews/airconditioning/ZonesView.qml @@ -22,14 +22,15 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtGraphicalEffects 1.0 -import QtCharts 2.2 -import Nymea 1.0 -import Nymea.AirConditioning 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Qt5Compat.GraphicalEffects +import QtCharts +import Nymea +import Nymea.AirConditioning + import "qrc:/ui/components" import "qrc:/ui/delegates" diff --git a/nymea-app/ui/mainviews/dashboard/Dashboard.qml b/nymea-app/ui/mainviews/dashboard/Dashboard.qml index eb690f83..f2a77785 100644 --- a/nymea-app/ui/mainviews/dashboard/Dashboard.qml +++ b/nymea-app/ui/mainviews/dashboard/Dashboard.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtCharts 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts +import Nymea + import "../../components" import "../../delegates" diff --git a/nymea-app/ui/mainviews/dashboard/DashboardAddWizard.qml b/nymea-app/ui/mainviews/dashboard/DashboardAddWizard.qml index b885d295..9b91bc90 100644 --- a/nymea-app/ui/mainviews/dashboard/DashboardAddWizard.qml +++ b/nymea-app/ui/mainviews/dashboard/DashboardAddWizard.qml @@ -22,13 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtCharts 2.2 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts +import Nymea +import NymeaApp.Utils + import "../../components" import "../../delegates" import "../../customviews" diff --git a/nymea-app/ui/mainviews/dashboard/DashboardDelegateBase.qml b/nymea-app/ui/mainviews/dashboard/DashboardDelegateBase.qml index 30086530..64f27123 100644 --- a/nymea-app/ui/mainviews/dashboard/DashboardDelegateBase.qml +++ b/nymea-app/ui/mainviews/dashboard/DashboardDelegateBase.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtCharts 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts +import Nymea + import "../../components" import "../../delegates" diff --git a/nymea-app/ui/mainviews/dashboard/DashboardFolderDelegate.qml b/nymea-app/ui/mainviews/dashboard/DashboardFolderDelegate.qml index 1d3a2cec..7d2f32c1 100644 --- a/nymea-app/ui/mainviews/dashboard/DashboardFolderDelegate.qml +++ b/nymea-app/ui/mainviews/dashboard/DashboardFolderDelegate.qml @@ -22,13 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtCharts 2.2 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts +import Nymea +import NymeaApp.Utils + import "../../components" import "../../delegates" diff --git a/nymea-app/ui/mainviews/dashboard/DashboardGraphDelegate.qml b/nymea-app/ui/mainviews/dashboard/DashboardGraphDelegate.qml index b7f164fa..30ca1b99 100644 --- a/nymea-app/ui/mainviews/dashboard/DashboardGraphDelegate.qml +++ b/nymea-app/ui/mainviews/dashboard/DashboardGraphDelegate.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtCharts 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts +import Nymea + import "../../components" import "../../customviews" diff --git a/nymea-app/ui/mainviews/dashboard/DashboardPage.qml b/nymea-app/ui/mainviews/dashboard/DashboardPage.qml index 53bb0403..96da989e 100644 --- a/nymea-app/ui/mainviews/dashboard/DashboardPage.qml +++ b/nymea-app/ui/mainviews/dashboard/DashboardPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtCharts 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts +import Nymea + import "../../components" import "../../delegates" diff --git a/nymea-app/ui/mainviews/dashboard/DashboardSceneDelegate.qml b/nymea-app/ui/mainviews/dashboard/DashboardSceneDelegate.qml index fe4eeee1..f011e51f 100644 --- a/nymea-app/ui/mainviews/dashboard/DashboardSceneDelegate.qml +++ b/nymea-app/ui/mainviews/dashboard/DashboardSceneDelegate.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtCharts 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts +import Nymea + import "../../components" import "../../delegates" diff --git a/nymea-app/ui/mainviews/dashboard/DashboardSensorDelegate.qml b/nymea-app/ui/mainviews/dashboard/DashboardSensorDelegate.qml index 7fd1aa1d..26b831de 100644 --- a/nymea-app/ui/mainviews/dashboard/DashboardSensorDelegate.qml +++ b/nymea-app/ui/mainviews/dashboard/DashboardSensorDelegate.qml @@ -22,13 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtCharts 2.2 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts +import Nymea +import NymeaApp.Utils + import "../../components" import "../../delegates" import "../../customviews" diff --git a/nymea-app/ui/mainviews/dashboard/DashboardStateDelegate.qml b/nymea-app/ui/mainviews/dashboard/DashboardStateDelegate.qml index e00d36df..5bcc84dc 100644 --- a/nymea-app/ui/mainviews/dashboard/DashboardStateDelegate.qml +++ b/nymea-app/ui/mainviews/dashboard/DashboardStateDelegate.qml @@ -22,13 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtCharts 2.2 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts +import Nymea +import NymeaApp.Utils + import "../../components" import "../../delegates" diff --git a/nymea-app/ui/mainviews/dashboard/DashboardThingDelegate.qml b/nymea-app/ui/mainviews/dashboard/DashboardThingDelegate.qml index 73460d01..49b153d2 100644 --- a/nymea-app/ui/mainviews/dashboard/DashboardThingDelegate.qml +++ b/nymea-app/ui/mainviews/dashboard/DashboardThingDelegate.qml @@ -22,13 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtCharts 2.2 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts +import Nymea +import NymeaApp.Utils + import "../../components" import "../../delegates" diff --git a/nymea-app/ui/mainviews/dashboard/DashboardWebViewDelegate.qml b/nymea-app/ui/mainviews/dashboard/DashboardWebViewDelegate.qml index a134ba1a..58d7afba 100644 --- a/nymea-app/ui/mainviews/dashboard/DashboardWebViewDelegate.qml +++ b/nymea-app/ui/mainviews/dashboard/DashboardWebViewDelegate.qml @@ -22,16 +22,17 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtCharts 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts +import Qt5Compat.GraphicalEffects +import Nymea + import "../../components" import "../../delegates" -//import QtWebView 1.1 -import QtGraphicalEffects 1.1 +//import QtWebView DashboardDelegateBase { id: root @@ -70,9 +71,9 @@ DashboardDelegateBase { property string webViewString: ' - import QtQuick 2.8; - import QtWebView 1.1; - import Nymea 1.0; + import QtQuick; + import QtWebView; + import Nymea; WebView { id: webView diff --git a/nymea-app/ui/mainviews/energy/ConsumerStats.qml b/nymea-app/ui/mainviews/energy/ConsumerStats.qml index 2c39c990..b2ce8acf 100644 --- a/nymea-app/ui/mainviews/energy/ConsumerStats.qml +++ b/nymea-app/ui/mainviews/energy/ConsumerStats.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import QtCharts 2.3 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtCharts +import Nymea +import NymeaApp.Utils + import "qrc:/ui/components/" StatsBase { diff --git a/nymea-app/ui/mainviews/energy/ConsumerStatsPage.qml b/nymea-app/ui/mainviews/energy/ConsumerStatsPage.qml index 3040213b..2d18cd58 100644 --- a/nymea-app/ui/mainviews/energy/ConsumerStatsPage.qml +++ b/nymea-app/ui/mainviews/energy/ConsumerStatsPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea + import "qrc:/ui/components" Page { diff --git a/nymea-app/ui/mainviews/energy/ConsumersHistory.qml b/nymea-app/ui/mainviews/energy/ConsumersHistory.qml index 78a5b6e5..2324f4b7 100644 --- a/nymea-app/ui/mainviews/energy/ConsumersHistory.qml +++ b/nymea-app/ui/mainviews/energy/ConsumersHistory.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import QtCharts 2.3 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtCharts +import QtQuick.Layouts +import QtQuick.Controls +import Nymea +import NymeaApp.Utils + import "qrc:/ui/components" Item { @@ -45,7 +46,7 @@ Item { sampleRate: d.sampleRate Component.onCompleted: fetchLogs() - onEntriesAddedIdx: { + onEntriesAddedIdx: (index, count) => { print("entries added", index, count) for (var i = 0; i < count; i++) { var entry = powerBalanceLogs.get(index + i) @@ -495,11 +496,11 @@ Item { thingId: consumerDelegate.thing.id loader: logsLoader - onEntriesAddedIdx: { + onEntriesAddedIdx: (index, count) => { addTimer.addEntries(index, count) } - onEntriesRemoved: { + onEntriesRemoved: (index, count) => { // Note QtCharts crash when calling removePoints() for points that don't exist. // Additionally it may decide to ignore values we add, e.g. if we try to add an Inf or undefined value for whatever reason // So, even though in theory the series should always 1:1 reflect the model, it may not do so in practice and we'll have to make sure not crash here diff --git a/nymea-app/ui/mainviews/energy/ConsumersHistoryPage.qml b/nymea-app/ui/mainviews/energy/ConsumersHistoryPage.qml index ff510c96..196d3a93 100644 --- a/nymea-app/ui/mainviews/energy/ConsumersHistoryPage.qml +++ b/nymea-app/ui/mainviews/energy/ConsumersHistoryPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea + import "qrc:/ui/components" Page { diff --git a/nymea-app/ui/mainviews/energy/ConsumersPieChart.qml b/nymea-app/ui/mainviews/energy/ConsumersPieChart.qml index a184af1c..3483ea58 100644 --- a/nymea-app/ui/mainviews/energy/ConsumersPieChart.qml +++ b/nymea-app/ui/mainviews/energy/ConsumersPieChart.qml @@ -22,13 +22,15 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtCharts 2.2 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Qt5Compat.GraphicalEffects +import QtCharts +import Nymea +import NymeaApp.Utils + import "qrc:/ui/components" Item { diff --git a/nymea-app/ui/mainviews/energy/ConsumersPieChartPage.qml b/nymea-app/ui/mainviews/energy/ConsumersPieChartPage.qml index c0f68b2e..fdba7263 100644 --- a/nymea-app/ui/mainviews/energy/ConsumersPieChartPage.qml +++ b/nymea-app/ui/mainviews/energy/ConsumersPieChartPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea + import "qrc:/ui/components" Page { diff --git a/nymea-app/ui/mainviews/energy/CurrentConsumptionBalancePieChart.qml b/nymea-app/ui/mainviews/energy/CurrentConsumptionBalancePieChart.qml index 1029f685..fc3b55a2 100644 --- a/nymea-app/ui/mainviews/energy/CurrentConsumptionBalancePieChart.qml +++ b/nymea-app/ui/mainviews/energy/CurrentConsumptionBalancePieChart.qml @@ -22,13 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtCharts 2.2 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts +import Nymea +import NymeaApp.Utils ChartView { id: consumptionPieChart diff --git a/nymea-app/ui/mainviews/energy/CurrentPowerBalancePage.qml b/nymea-app/ui/mainviews/energy/CurrentPowerBalancePage.qml index 1ee9a81a..e308954a 100644 --- a/nymea-app/ui/mainviews/energy/CurrentPowerBalancePage.qml +++ b/nymea-app/ui/mainviews/energy/CurrentPowerBalancePage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea + import "qrc:/ui/components" Page { diff --git a/nymea-app/ui/mainviews/energy/CurrentPowerBalancePieChart.qml b/nymea-app/ui/mainviews/energy/CurrentPowerBalancePieChart.qml index fb0c4fe5..3b2b5b39 100644 --- a/nymea-app/ui/mainviews/energy/CurrentPowerBalancePieChart.qml +++ b/nymea-app/ui/mainviews/energy/CurrentPowerBalancePieChart.qml @@ -22,14 +22,15 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtGraphicalEffects 1.0 -import QtCharts 2.2 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Qt5Compat.GraphicalEffects +import QtCharts +import Nymea +import NymeaApp.Utils + import "qrc:/ui/components" Item { diff --git a/nymea-app/ui/mainviews/energy/CurrentProductionBalancePieChart.qml b/nymea-app/ui/mainviews/energy/CurrentProductionBalancePieChart.qml index b7117836..d6757c07 100644 --- a/nymea-app/ui/mainviews/energy/CurrentProductionBalancePieChart.qml +++ b/nymea-app/ui/mainviews/energy/CurrentProductionBalancePieChart.qml @@ -22,13 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.2 -import QtCharts 2.2 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCharts + +import Nymea +import NymeaApp.Utils ChartView { id: productionPieChart diff --git a/nymea-app/ui/mainviews/energy/EnergySettingsPage.qml b/nymea-app/ui/mainviews/energy/EnergySettingsPage.qml index 5492ccf2..8a980adf 100644 --- a/nymea-app/ui/mainviews/energy/EnergySettingsPage.qml +++ b/nymea-app/ui/mainviews/energy/EnergySettingsPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea + import "qrc:/ui/components" SettingsPageBase { @@ -74,7 +75,7 @@ SettingsPageBase { textRole: "name" currentIndex: rootMeterProxy.indexOf(rootMeterProxy.getThing(energyManager.rootMeterId)) - onActivated: { + onActivated: (index) => { energyManager.setRootMeterId(rootMeterProxy.get(index).id) } } diff --git a/nymea-app/ui/mainviews/energy/PowerBalanceHistory.qml b/nymea-app/ui/mainviews/energy/PowerBalanceHistory.qml index a4f6ebdb..961dfaf0 100644 --- a/nymea-app/ui/mainviews/energy/PowerBalanceHistory.qml +++ b/nymea-app/ui/mainviews/energy/PowerBalanceHistory.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import QtCharts 2.2 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import Nymea 1.0 +import QtQuick +import QtCharts +import QtQuick.Layouts +import QtQuick.Controls +import Nymea + import "qrc:/ui/components" Item { @@ -104,7 +105,7 @@ Item { Connections { target: powerBalanceLogs - onEntriesAddedIdx: { + onEntriesAddedIdx: (index, count) => { // print("entries added", index, count) selfProductionConsumptionSeries.upperSeries = null selfProductionConsumptionSeries.lowerSeries = null diff --git a/nymea-app/ui/mainviews/energy/PowerBalanceHistoryPage.qml b/nymea-app/ui/mainviews/energy/PowerBalanceHistoryPage.qml index 70b181bb..641661d6 100644 --- a/nymea-app/ui/mainviews/energy/PowerBalanceHistoryPage.qml +++ b/nymea-app/ui/mainviews/energy/PowerBalanceHistoryPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea + import "qrc:/ui/components" Page { diff --git a/nymea-app/ui/mainviews/energy/PowerBalanceStats.qml b/nymea-app/ui/mainviews/energy/PowerBalanceStats.qml index 96e5b8f0..93f006eb 100644 --- a/nymea-app/ui/mainviews/energy/PowerBalanceStats.qml +++ b/nymea-app/ui/mainviews/energy/PowerBalanceStats.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import QtCharts 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtCharts +import Nymea + import "qrc:/ui/components/" StatsBase { diff --git a/nymea-app/ui/mainviews/energy/PowerBalanceStatsPage.qml b/nymea-app/ui/mainviews/energy/PowerBalanceStatsPage.qml index 318996c0..06a1a35a 100644 --- a/nymea-app/ui/mainviews/energy/PowerBalanceStatsPage.qml +++ b/nymea-app/ui/mainviews/energy/PowerBalanceStatsPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.3 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea + import "qrc:/ui/components" Page { diff --git a/nymea-app/ui/mainviews/energy/PowerConsumptionBalanceHistory.qml b/nymea-app/ui/mainviews/energy/PowerConsumptionBalanceHistory.qml index b567052b..703753d5 100644 --- a/nymea-app/ui/mainviews/energy/PowerConsumptionBalanceHistory.qml +++ b/nymea-app/ui/mainviews/energy/PowerConsumptionBalanceHistory.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import QtCharts 2.2 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.3 -import Nymea 1.0 +import QtQuick +import QtCharts +import QtQuick.Layouts +import QtQuick.Controls +import Nymea + import "qrc:/ui/components" Item { diff --git a/nymea-app/ui/mainviews/energy/PowerProductionBalanceHistory.qml b/nymea-app/ui/mainviews/energy/PowerProductionBalanceHistory.qml index d3247141..4b16fcca 100644 --- a/nymea-app/ui/mainviews/energy/PowerProductionBalanceHistory.qml +++ b/nymea-app/ui/mainviews/energy/PowerProductionBalanceHistory.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import QtCharts 2.2 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.2 -import Nymea 1.0 +import QtQuick +import QtCharts +import QtQuick.Layouts +import QtQuick.Controls +import Nymea + import "qrc:/ui/components" Item { diff --git a/nymea-app/ui/mainviews/energy/StatsBase.qml b/nymea-app/ui/mainviews/energy/StatsBase.qml index e6ca9cb3..db9c3b8d 100644 --- a/nymea-app/ui/mainviews/energy/StatsBase.qml +++ b/nymea-app/ui/mainviews/energy/StatsBase.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.0 -import Nymea 1.0 +import QtQuick +import Nymea Item { id: root diff --git a/nymea-app/ui/shaders/brightnesscircle.frag.qsb b/nymea-app/ui/shaders/brightnesscircle.frag.qsb new file mode 100644 index 0000000000000000000000000000000000000000..bad572945eec9c0818b7fe5cbfe76e5c8172d3a6 GIT binary patch literal 1868 zcmV-S2ebG902*L;ob6d#bJIo?-o#D}CX`#C1ws*o5}CTfm?Q*pAtmA3fK!s8oylZ` zV#|(NTQbrboHCi|W1srcnf`)4^(XX?^)l0G&)Gd|uVsfM9r{40n^C0w_B;2pD`mnM zJIEMI!qo@Y2kZso%x0_1Wlgrg0{978iRECeA1?M64c23zg5#_V0uHMP;i?dq>UR|# zWE-pj;`n5ZN~=!2}1@o?sjz#=OQpsvd?(q`>MRR0I*uw#ekX@-04& zg5wP!#)DYaHS6O&(Cc^6pYKFJ4!Spi=CTOxC{!Ys>N~kK4C%puD z14%Fn+y_}XnA~ur9@bG)f~^4@{El!Olv~mDbxW^hv9yaY^eDK(t~r9`;gWj!2Aq7 z4~Y3dYd+fIw6PSEWmH%n@#ZzGpRi>OOAz*4!;*y6HEe(|E__Y2^r7D)vA9MkE;S$1 z;yM9R{bD^KY~%AOc*5csaJ>)w6csBeuq0GQ#)sEwI1AFW9`6b@KMVSBzokijh;YQF zX?~b6w0DH`^%MUnQ?-?RoF60XB+Q4&R~#SH{3NZT{3)hR3p}lo;Is5SDe`bY>6Pxy9}1lR-WW@v~H1aSjP#<_jN7qNy5LU{N5lPlbZiiB&YIs zi(6s>6$;^<9ig}i>nOMxqx49m^-6nh)W~gJHFm-(gvKgU6>Yvx@us}ZE(R^AY zT={gDu*H~9L%>G+_Xt}c8+Wy}`?Qv$*zajIctGp=H3T+s?IFool4=AoA~!Y~<@D>c0i)*dapMKIA3Hqs zn$rRk8W1ehoubFLB>K`VjvGOPF9g*f)F98-5Gl$xLpRzCswExV2*D5TyHPZq-Ue41 zzE=*y8v0_``6&&N4o6O{UUkF#q7em+u;>Eer4w#>eg*C3(Z5xEp)qT4x5*o!n_n~~p6$?*k?wkB!_;AG%a}tCt#$+%L6l~2RI2v9(5Wms z+*!-5gQ1$&G||3^aw=(7bL*R|am~tQj4Qfh)~l>O%?i)Wh`V(m-pXdyD0vZg{Gw~> z(xBD2iZa(b;8&Tf@S5s_v{d^L6u9|yP%cL}20NMGyRNOV@LEI)ku%w7nCD6${=^#-T9 z_0R^ESMPqgP$)cI%*lXy=qNOJOo?U|G^{+cSDmopa#A7oGZO5MO-+)W+gi>nnH@8h zmwoMWdvCiO)YeVuimCTkYonKU+v#eP+k4yO9jdHmvzgVqRc>*Fo3zdCx46x_t0>Re zt`32qoQexh!LzDYN1x2<46Cytl`m9o3G^^6H3VWJNjhTb;b>hgP8=6DnIBWIt)F5^ z@rP1tBz_w8{9?6Ha*dgq%bltn@lw^>m`k_u$g7pE;xB7+4qjyuek%D+&5a=Wt|6p) z{r%B8^Y-)(rl#+F3lsQH-^1h*MxMiL?6fo2){1yHbD8z^9+IB_hI3(Utr5X#R1J!L zTO3u_TwgOSpG>6?LIO$EDeLQ5qZs(OGeiO}V|&B8e7^{{vaN5-k~~0L=jYm*dgDu; zIx6Mz3QRCSLIo$&`an|7;WcZ#-k#p|{E>Q0O?eh#v359qVk>+2&In@tjo%vWLumhB z8zj5W?+qdKuY7UDk+ZXrmfT$LIhQvNaC$OXd literal 0 HcmV?d00001 diff --git a/nymea-app/ui/shaders/coloricon.frag b/nymea-app/ui/shaders/coloricon.frag index bdae5db2..cd572532 100644 --- a/nymea-app/ui/shaders/coloricon.frag +++ b/nymea-app/ui/shaders/coloricon.frag @@ -11,9 +11,9 @@ layout(std140, binding = 0) uniform buf { vec4 inColor; vec4 outColor; float threshold; -} ubuf; +}; void main() { - lowp vec4 sourceColor = texture(source, qt_TexCoord0); - fragColor = mix(vec4(ubuf.outColor.rgb, 1.0) * sourceColor.a, sourceColor, step(ubuf.threshold, distance(sourceColor.rgb / sourceColor.a, ubuf.inColor.rgb))) * ubuf.qt_Opacity; + vec4 sourceColor = texture(source, qt_TexCoord0); + fragColor = mix(vec4(outColor.rgb, 1.0) * sourceColor.a, sourceColor, step(threshold, distance(sourceColor.rgb / sourceColor.a, inColor.rgb))) * qt_Opacity; } diff --git a/nymea-app/ui/shaders/coloricon.frag.qsb b/nymea-app/ui/shaders/coloricon.frag.qsb index a3d95cb2290c09b6b7c960f87e88b6585f80f760..687aee4e0047754dae2897c60b7b64b56102bcc9 100644 GIT binary patch literal 1677 zcmV;826FiT02W?&ob6a!Zxcrpp4d*@m~bbM6etU6VGU++jLj`LgeJWpfs&GlRV&zU*19&bz%sy-B{Q*FKHn{&Q%o3j(a7@K5_ zW#AcuXNJ9EoY`!HxvbBYSpffqtig(~mx71=MT?DCNN|cZ!N6fHVcZtxlKw!`3AV+0 zV2*D#E3pc^aZP7j(98IqfeQ}Q9z@C55z<)Fv`?s)Gi0*Lx?ofX6V7(X<&ugmxsHLF zzbAz?omXEcK&c13NrRW~GB^dw+o0yM2!7G1K_PYD6_Q%0GzDhpF@$_vkWH%V*nWnG zT@&=%(4eJsYA%cXN7zS@rCcZBNTA0fV1mD2JzallMZ95^D|lX@i0L@u<18!E!l&bS zzO-j-nqh^~0?#4`yd8z#E967Tmx%{uwEINcpVs8BK|V+C<3b*f<+)gAfMuENkiy1D zZ%M;agso{*2BnGrOAESMguW9zC7N7EWQ|pCA{QCY~!j$}o;=KcBCB+6Kjz0bXWSnxv zzD|a4q z7{!Wleghns*A=Zs3Y*jVps-H~L)$g*guXr_`#IXbOtE2I^OWy3iVZog6aEY3cY`>t zYw;Jz4tcQtwf+6JSJTA=yT$E%;XuIChSjOz9+vz8T#&{pl&8}r3tt{b{_ zPe|KdYrAVS+kwLu_Q0MGU@qceug;CFUNiSLXTa(>yllMU_A`fvUVlMgf&szRu2c8; zjznL(^)j$52kju#kf6skNSgBP(2cf(c4Hy83r>5!*9^iAdNu4)MMGq0k<;n6-LSM` zL_sgCyP)ve33oidg)T}M$%fls4uY^z#J#|47+4xJPf3VCq^*d>s2beu^IqtdR!oT( zhFJ14+E&~CGIUxi4tHwBO|a^CeG|z{2-8xTS^b?K3&y-v%p2ErFV>raE*3->X2jjD zFprB+FdAOO9l!3Hx;3yGx6tPH5d0=zz#>^xX;jO@0@sM@P1()m5{IPE;x+c$;E{f{|6?AE8~wxpFgR)>N& z-B8s1ff2eb2*M4`t)ePd7`(AN&i9bG=v%p8Mi+K`9KZ@({SY*pk;~0`TrbgN(xhM# zs%2eOvQjz;#mZhqRrQ4Coju;;`X)5*=H>P#I>(;a*+FkvymR-tb|i$y;B0^8AIp90pNjKk>UgPOTWh2A(&*_-=W1_4!Is zCNzR$wZ{`AnpQlKG(=_f`~8A`?&KID+^12p6Qi`Ztn%Zsr)3bB({h0r-czgy##o|*Ifdb`(fjfWkVJ8e7S zjkdS7m>b}c*J<3s|5@9M@coYPR`#8a8$khGLs*UaQ!@Up9O{apQ#f?V5O#=bhMZ%L zMa=tMLs6^M@z*ToH#bLEdj38mS*!IT_z<*%x<4>S>W=GcuH~Dl2q7b|RA*vyvtZN% zAJ4HU)m1!ZOpUw%xmY76KS-QOyhjJa|Nb{A*}mspDy;tLZK};qAV&sgW?a;buGhpBEB`eY X*NA^QObpq+x{TzcjaYvJKXu5i%jjQf literal 1741 zcmV;;1~T~o02bDGob6a!bJIo?-rT{2J0VHA3BpAVMmWadW}Jj3EoBBKDap{zcrr$@ zWk;9K_IK0P#3Lo0Qang9PasCB6<* z`F`e&6NIks8FRU8DiuaSyAl~&?ON(x%7CkBM|tCQRDNzpf!iratk&@D2*K5sU2&rw zg}!krdBgRV{e~Yf#BWCoQlimz;DpJ>-8S8C^lNsrU8AeV^ z$;TPU7*#inY_H;&TpZLIw^8U$5BxTrkr}cm&&ZdC3ye#c*JL-9!iK_Z2sOI7Zrz6` zE5KiK0-5xOM&Q)J4JRuB1BijGAN^V_bRx5&Gp9Glr?Bx<)jl*<@kEtBZlZd0S)EQN)6;xvo)GWonJOn{YHw=Q7tWrtfp2!* z0nM=1N$e?Jk#ktRU7}M(HBdkw(@KLc3B|+_i)Wj)njCKjI^Rnu*yUdtcvaccdQkc|B;&;OSyXxTrI-!)e~5C4_cT;9CA#k){L=I}(1$N` zDUu&29I*n?M+rlF$4TEH@t+X7#}q%(Ckey-GeXs9jP{Y9AZ!Zgv$Ti)Uxd}9j8WOp zag36#DY83Bx~61|3Y!4>3(5=HzDe{svW32%CtX9N?*hq=5&x*rz3}rQ>bp+*1nnbz zgUOrBKW*<8tA$1S`Tjk^G`&dv-i6*B6x|n5wDAWZBNQvv^)T5h0*&=KMztwYT~1N% zzXK`cJ54-@FVJiw_89gr2sNwIl%pc`(j~%I!Qy#}{}SDTd__OM1sxdI6_z87&9FLX z>?&a>y9Sof)-{r!q5aF`8|F1l@!lZcP{%CczfycRNyjYnKSOe;2lIcMV!XxlWC_!P;yVJ+FJmG6Vp^kaN^!*FSo|ko2`sZ04?vs!Am`@J~*FHTY>_Nh( zao`@6J)*E>vhk4ZJ)*rV-33;IBJJ~g9Bks=0?ApF>kRSh+%A#di!2Y13D-6HlJq-9Swff;3wzjS`eiRqy85`WY9%#TV~ ze|;v$?mpYCe>R(H1y044)V5pSZmDt=_Q0+e75;m@qI~<;hw7$Nb=%F>|A%Ypm|^*4 z6<YYKL%aZuk|iD~_t0 zj>k-^m8lg%L?Ee8Pn(+=qvCs5Xql?(vRuHRe&LXQW#Y!Hs-u2<(l3?tx0~YAhkCWW z4g^L>sN{*KAodRLqVaCG@WGR^(ql5^83@MeGb4WD_=Y3G&dQ%YBqaQ)VPOYj;5n6M8H^kD~l{0pD~CEQEl1%L2@5sL_JK@$xuXi4L?G*|Q&noh$Z^w6B{ zOeo_Yz^;Z#NqTj@=jcKpwTq_&m}SJahQ1NqEU?KQbkWF069K2}ayvTPxJ5qaAjB|w z=*`Bg0OUA`iBSgcKnJ~qaC{N)s%x4*8w1s3Ih|U~5dSRt{g|~k@zCUP7ES2$>u0rR z#ZWYg<;PS-xDIKFqrG{^$oT2%Sgxn+0oH&Ln3nnsap2uG{QQ7@MDhdXA(`w}wEe{d zeldYx)9~M*yw3MiQl5(C)fh9-Wk3};(oHaKTXLtRF2#NdiE|YA9JJm=R7%QenH9QU z#5+p1f!7_xXE^zjQa6d2R{rT)#^K5GezMAu{2uaAgJ#)&j`gIguzZbmX z=XsCvwZe7HGe6ls;@H;Np5y}SKE-;bU@()!`5S7c7)!aI(R?q+7?oT_nR0ra^I7Fw z-r{_Hhb$RcbA=)O7J8UrU1WcU^Y;bf@5=fq`(?&Z9QRlsVOAJ(U&Fl5`WJ|q=NjB& zeRP%w?2q=oMIG6#vOdk{yUn^P_u@yKgUHWA&cTn&nPbdDwqIl2?^xx}R98;&tdr1y zxK$^9UOjPw(DglIqg2Xv1IKoybmX>k?B{C{iklU4(7P=m++ff~5psPy|iq4M3taAkN`EXkD% z@^{J+AMSFMpqIwxpc3g{Y|LEK31k94Hv*^ShQbMQhovaKz<*C0E|d(smEGvIBkSb{e11KgFXhd^m>m zuJNpn6XGN~hO`>>tt6iHOFf0zoK9JylaK4ldfleaTq%EWFv8OH{$eKT^$J1P^yIe$w-@4E;s_MZ(A%6Ka)N>(z*wpLMQ<&&S;N;_DfZC9#=vkpiYA8^Y ztYxMMLj*|#vE<{oUK9geRpaeh<-!qFJUPvM0YffcZbI2OK36=Q2?iR_q)MAnKhf4B t=TvKOU-dOL_LPj7-%E*illmQnmiF^NbR{O?+;1*A7RK1f^(S~_3d7&f*;oJo literal 0 HcmV?d00001 diff --git a/nymea-app/ui/system/AboutNymeaPage.qml b/nymea-app/ui/system/AboutNymeaPage.qml index 38a77e58..cb723d01 100644 --- a/nymea-app/ui/system/AboutNymeaPage.qml +++ b/nymea-app/ui/system/AboutNymeaPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" SettingsPageBase { diff --git a/nymea-app/ui/system/AdvancedConnectionInterfacesPage.qml b/nymea-app/ui/system/AdvancedConnectionInterfacesPage.qml index 0ae1b0b0..93bf423a 100644 --- a/nymea-app/ui/system/AdvancedConnectionInterfacesPage.qml +++ b/nymea-app/ui/system/AdvancedConnectionInterfacesPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" SettingsPageBase { diff --git a/nymea-app/ui/system/ConnectionInterfaceDelegate.qml b/nymea-app/ui/system/ConnectionInterfaceDelegate.qml index bd3c3aab..a894d78c 100644 --- a/nymea-app/ui/system/ConnectionInterfaceDelegate.qml +++ b/nymea-app/ui/system/ConnectionInterfaceDelegate.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" NymeaSwipeDelegate { diff --git a/nymea-app/ui/system/ConnectionInterfacesPage.qml b/nymea-app/ui/system/ConnectionInterfacesPage.qml index 2442058f..196d567b 100644 --- a/nymea-app/ui/system/ConnectionInterfacesPage.qml +++ b/nymea-app/ui/system/ConnectionInterfacesPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" SettingsPageBase { diff --git a/nymea-app/ui/system/DeveloperTools.qml b/nymea-app/ui/system/DeveloperTools.qml index 5cb7bce5..4ebe818f 100644 --- a/nymea-app/ui/system/DeveloperTools.qml +++ b/nymea-app/ui/system/DeveloperTools.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" SettingsPageBase { @@ -107,7 +108,7 @@ SettingsPageBase { var path = engine.jsonRpcClient.currentConnection.hostAddress + ":" + root.usedConfig.port + "/debug" return qsTr("Debug interface active at %1.").arg('' + proto + path + '') } - onLinkActivated: Qt.openUrlExternally(link) + onLinkActivated: (link) => Qt.openUrlExternally(link) } SettingsPageSectionHeader { diff --git a/nymea-app/ui/system/GeneralSettingsPage.qml b/nymea-app/ui/system/GeneralSettingsPage.qml index e0b4fb6f..43487d38 100644 --- a/nymea-app/ui/system/GeneralSettingsPage.qml +++ b/nymea-app/ui/system/GeneralSettingsPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" SettingsPageBase { @@ -202,7 +203,7 @@ SettingsPageBase { Layout.minimumWidth: 200 model: engine.systemController.timeZones currentIndex: model.indexOf(engine.systemController.serverTimeZone) - onActivated: { + onActivated: (index) => { engine.systemController.serverTimeZone = currentText; } } diff --git a/nymea-app/ui/system/LogViewerPage.qml b/nymea-app/ui/system/LogViewerPage.qml index d7965d38..7d47ffc6 100644 --- a/nymea-app/ui/system/LogViewerPage.qml +++ b/nymea-app/ui/system/LogViewerPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material +import Nymea + import "../components" Page { @@ -88,8 +89,9 @@ Page { delegate: NymeaItemDelegate { id: delegate width: listView.width - leftPadding: 0 - rightPadding: 0 + + leftPadding: app.margins + rightPadding: app.margins topPadding: 0 bottomPadding: 0 property NewLogEntry entry: newLogsModel.get(index) diff --git a/nymea-app/ui/system/LogViewerPagePre18.qml b/nymea-app/ui/system/LogViewerPagePre18.qml index 6a12c9c2..9d906d22 100644 --- a/nymea-app/ui/system/LogViewerPagePre18.qml +++ b/nymea-app/ui/system/LogViewerPagePre18.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material +import Nymea + import "../components" Page { diff --git a/nymea-app/ui/system/ModbusRtuAddMasterPage.qml b/nymea-app/ui/system/ModbusRtuAddMasterPage.qml index b3cd63a5..7be622d7 100644 --- a/nymea-app/ui/system/ModbusRtuAddMasterPage.qml +++ b/nymea-app/ui/system/ModbusRtuAddMasterPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" -import Nymea 1.0 SettingsPageBase { id: root @@ -160,7 +161,7 @@ SettingsPageBase { Layout.minimumWidth: 250 textRole: "value" enabled: !root.busy - onActivated: console.log("Selected baud rate", currentText, model.get(currentIndex).value) + onActivated: (index) => console.log("Selected baud rate", currentText, model.get(index).value) model: serialPortBaudrateModel } } @@ -178,7 +179,7 @@ SettingsPageBase { textRole: "text" enabled: !root.busy Layout.minimumWidth: 250 - onActivated: console.log("Selected parity", currentText, model.get(currentIndex).value) + onActivated: (index) => console.log("Selected parity", currentText, model.get(index).value) model: serialPortParityModel } } @@ -196,7 +197,7 @@ SettingsPageBase { textRole: "text" enabled: !root.busy Layout.minimumWidth: 250 - onActivated: console.log("Selected data bits", currentText, model.get(currentIndex).value) + onActivated: (index) => console.log("Selected data bits", currentText, model.get(index).value) model: serialPortDataBitsModel Component.onCompleted: { currentIndex = 3 @@ -217,7 +218,7 @@ SettingsPageBase { textRole: "text" enabled: !root.busy Layout.minimumWidth: 250 - onActivated: console.log("Selected stop bits", currentText, model.get(currentIndex).value) + onActivated: (index) => console.log("Selected stop bits", currentText, model.get(index).value) model: serialPortStopBitsModel } } diff --git a/nymea-app/ui/system/ModbusRtuReconfigureMasterPage.qml b/nymea-app/ui/system/ModbusRtuReconfigureMasterPage.qml index e26d1c14..942dd0ce 100644 --- a/nymea-app/ui/system/ModbusRtuReconfigureMasterPage.qml +++ b/nymea-app/ui/system/ModbusRtuReconfigureMasterPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" -import Nymea 1.0 SettingsPageBase { id: root @@ -175,7 +176,7 @@ SettingsPageBase { enabled: !root.busy textRole: "value" model: serialPortBaudrateModel - onActivated: console.log("Selected baudrate", currentText, model.get(currentIndex).value) + onActivated: (index) => console.log("Selected baudrate", currentText, model.get(index).value) Component.onCompleted: { for (var i = 0; i < serialPortBaudrateModel.count; i++) { if (serialPortBaudrateModel.get(i).value === modbusRtuMaster.baudrate) { @@ -199,7 +200,7 @@ SettingsPageBase { textRole: "text" enabled: !root.busy Layout.minimumWidth: 250 - onActivated: console.log("Selected parity", currentText, model.get(currentIndex).value) + onActivated: (index) => console.log("Selected parity", currentText, model.get(index).value) model: serialPortParityModel Component.onCompleted: { for (var i = 0; i < serialPortParityModel.count; i++) { @@ -224,7 +225,7 @@ SettingsPageBase { textRole: "text" enabled: !root.busy Layout.minimumWidth: 250 - onActivated: console.log("Selected data bits", currentText, model.get(currentIndex).value) + onActivated: (index) => console.log("Selected data bits", currentText, model.get(index).value) model: serialPortDataBitsModel Component.onCompleted: { for (var i = 0; i < serialPortDataBitsModel.count; i++) { @@ -249,7 +250,7 @@ SettingsPageBase { textRole: "text" enabled: !root.busy Layout.minimumWidth: 250 - onActivated: console.log("Selected stop bits", currentText, model.get(currentIndex).value) + onActivated: (index) => console.log("Selected stop bits", currentText, model.get(index).value) model: serialPortStopBitsModel Component.onCompleted: { for (var i = 0; i < serialPortStopBitsModel.count; i++) { diff --git a/nymea-app/ui/system/ModbusRtuSettingsPage.qml b/nymea-app/ui/system/ModbusRtuSettingsPage.qml index 9188cd90..0a702a5b 100644 --- a/nymea-app/ui/system/ModbusRtuSettingsPage.qml +++ b/nymea-app/ui/system/ModbusRtuSettingsPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" -import Nymea 1.0 SettingsPageBase { id: root diff --git a/nymea-app/ui/system/MqttBrokerSettingsPage.qml b/nymea-app/ui/system/MqttBrokerSettingsPage.qml index 1698aeed..07a1ed12 100644 --- a/nymea-app/ui/system/MqttBrokerSettingsPage.qml +++ b/nymea-app/ui/system/MqttBrokerSettingsPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" SettingsPageBase { diff --git a/nymea-app/ui/system/MqttPolicyPage.qml b/nymea-app/ui/system/MqttPolicyPage.qml index 3fe29c05..692e158e 100644 --- a/nymea-app/ui/system/MqttPolicyPage.qml +++ b/nymea-app/ui/system/MqttPolicyPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" SettingsPageBase { diff --git a/nymea-app/ui/system/NetworkSettingsPage.qml b/nymea-app/ui/system/NetworkSettingsPage.qml index e176fb5b..c3af7c01 100644 --- a/nymea-app/ui/system/NetworkSettingsPage.qml +++ b/nymea-app/ui/system/NetworkSettingsPage.qml @@ -22,13 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Qt.labs.settings 1.1 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtCore -import Nymea 1.0 +import Nymea import "qrc:/ui/components" SettingsPageBase { @@ -570,8 +570,8 @@ SettingsPageBase { maximumLength: 32 Layout.fillWidth: true horizontalAlignment: Text.AlignRight - validator: RegExpValidator { - regExp: /^((?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.){0,3}(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$/ + validator: RegularExpressionValidator { + regularExpression: /^((?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.){0,3}(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$/ } } @@ -597,8 +597,8 @@ SettingsPageBase { id: defaultGwTextField maximumLength: 32 Layout.fillWidth: true - validator: RegExpValidator { - regExp: /^((?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.){0,3}(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$/ + validator: RegularExpressionValidator { + regularExpression: /^((?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.){0,3}(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$/ } } @@ -610,8 +610,8 @@ SettingsPageBase { id: dnsTextField maximumLength: 32 Layout.fillWidth: true - validator: RegExpValidator { - regExp: /^((?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.){0,3}(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$/ + validator: RegularExpressionValidator { + regularExpression: /^((?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.){0,3}(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$/ } } } diff --git a/nymea-app/ui/system/PackageDetailsPage.qml b/nymea-app/ui/system/PackageDetailsPage.qml index fdc63a2a..441dfc93 100644 --- a/nymea-app/ui/system/PackageDetailsPage.qml +++ b/nymea-app/ui/system/PackageDetailsPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" -import Nymea 1.0 SettingsPageBase { id: packageDetailsPage diff --git a/nymea-app/ui/system/PackageListPage.qml b/nymea-app/ui/system/PackageListPage.qml index 00db3140..517aa6ff 100644 --- a/nymea-app/ui/system/PackageListPage.qml +++ b/nymea-app/ui/system/PackageListPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" -import Nymea 1.0 SettingsPageBase { id: packageListPage diff --git a/nymea-app/ui/system/PluginParamsPage.qml b/nymea-app/ui/system/PluginParamsPage.qml index 9eca628b..c3454610 100644 --- a/nymea-app/ui/system/PluginParamsPage.qml +++ b/nymea-app/ui/system/PluginParamsPage.qml @@ -22,13 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" import "../delegates" -import Nymea 1.0 SettingsPageBase { id: root diff --git a/nymea-app/ui/system/PluginsPage.qml b/nymea-app/ui/system/PluginsPage.qml index 1aa3d580..dfb3aa58 100644 --- a/nymea-app/ui/system/PluginsPage.qml +++ b/nymea-app/ui/system/PluginsPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" -import Nymea 1.0 SettingsPageBase { id: root diff --git a/nymea-app/ui/system/ServerConfigurationDialog.qml b/nymea-app/ui/system/ServerConfigurationDialog.qml index 6042e0a9..49ad4e20 100644 --- a/nymea-app/ui/system/ServerConfigurationDialog.qml +++ b/nymea-app/ui/system/ServerConfigurationDialog.qml @@ -22,11 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea Dialog { id: root @@ -54,7 +54,7 @@ Dialog { ? 0 : root.serverConfiguration.address === "127.0.0.1" ? 1 : 2 - onActivated: { + onActivated: (index) => { switch (index) { case 0: root.serverConfiguration.address = "0.0.0.0"; diff --git a/nymea-app/ui/system/ServerLoggingCategoriesPage.qml b/nymea-app/ui/system/ServerLoggingCategoriesPage.qml index 5b493509..18831e9c 100644 --- a/nymea-app/ui/system/ServerLoggingCategoriesPage.qml +++ b/nymea-app/ui/system/ServerLoggingCategoriesPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" SettingsPageBase { diff --git a/nymea-app/ui/system/SystemUpdatePage.qml b/nymea-app/ui/system/SystemUpdatePage.qml index 309f975f..3f11bb72 100644 --- a/nymea-app/ui/system/SystemUpdatePage.qml +++ b/nymea-app/ui/system/SystemUpdatePage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "../components" -import Nymea 1.0 Page { id: root diff --git a/nymea-app/ui/system/TunnelProxyServerConfigurationDialog.qml b/nymea-app/ui/system/TunnelProxyServerConfigurationDialog.qml index a0bd1283..f04dc951 100644 --- a/nymea-app/ui/system/TunnelProxyServerConfigurationDialog.qml +++ b/nymea-app/ui/system/TunnelProxyServerConfigurationDialog.qml @@ -22,11 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea Dialog { id: root @@ -40,17 +40,15 @@ Dialog { ColumnLayout { anchors { left: parent.left; top: parent.top; right: parent.right } - RowLayout { - Label { - text: qsTr("Proxy server address:") - Layout.fillWidth: true - } - TextField { - id: addressTextField - Layout.fillWidth: true - text: root.serverConfiguration ? root.serverConfiguration.address : "" - onEditingFinished: root.serverConfiguration.address = text - } + Label { + text: qsTr("Proxy server address:") + Layout.fillWidth: true + } + TextField { + id: addressTextField + Layout.fillWidth: true + text: root.serverConfiguration ? root.serverConfiguration.address : "" + onEditingFinished: root.serverConfiguration.address = text } RowLayout { diff --git a/nymea-app/ui/system/UsersSettingsPage.qml b/nymea-app/ui/system/UsersSettingsPage.qml index 83b02fbd..75988440 100644 --- a/nymea-app/ui/system/UsersSettingsPage.qml +++ b/nymea-app/ui/system/UsersSettingsPage.qml @@ -22,12 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 -import NymeaApp.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts + +import Nymea +import NymeaApp.Utils + import "../components" SettingsPageBase { @@ -38,7 +40,7 @@ SettingsPageBase { id: userManager engine: _engine - onChangePasswordReply: { + onChangePasswordReply: (id, error) => { if (error !== UserManager.UserErrorNoError) { var component = Qt.createComponent("../components/ErrorDialog.qml") var text; @@ -173,9 +175,9 @@ SettingsPageBase { } Connections { target: userManager - onSetUserInfoReply: { + onSetUserInfoReply: (id, error) => { editUserInfoPage.busy = false - if (error != UserManager.UserErrorNoError) { + if (error !== UserManager.UserErrorNoError) { var component = Qt.createComponent("../components/ErrorDialog.qml") var text = qsTr("Un unexpected error happened when creating the user. We're sorry for this. (Error code: %1)").arg(error); var popup = component.createObject(app, {text: text}); @@ -421,7 +423,7 @@ SettingsPageBase { Connections { target: userManager - onRemoveUserReply: { + onRemoveUserReply: (id, error) => { userDetailsPage.busy = false if (error !== UserManager.UserErrorNoError) { var component = Qt.createComponent("../components/ErrorDialog.qml") @@ -528,7 +530,7 @@ SettingsPageBase { } Connections { target: userManager - onCreateUserReply: { + onCreateUserReply: (id, error) => { createUserPage.busy = false if (error !== UserManager.UserErrorNoError) { var component = Qt.createComponent("../components/ErrorDialog.qml") diff --git a/nymea-app/ui/system/WebServerConfigurationDialog.qml b/nymea-app/ui/system/WebServerConfigurationDialog.qml index ede9079f..08cd9f0d 100644 --- a/nymea-app/ui/system/WebServerConfigurationDialog.qml +++ b/nymea-app/ui/system/WebServerConfigurationDialog.qml @@ -22,11 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea Dialog { id: root @@ -54,7 +54,7 @@ Dialog { ? 0 : root.serverConfiguration.address === "127.0.0.1" ? 1 : 2 - onActivated: { + onActivated: (index) => { switch (index) { case 0: root.serverConfiguration.address = "0.0.0.0"; diff --git a/nymea-app/ui/system/WebServerSettingsPage.qml b/nymea-app/ui/system/WebServerSettingsPage.qml index 3cb8f90d..0c4af9a4 100644 --- a/nymea-app/ui/system/WebServerSettingsPage.qml +++ b/nymea-app/ui/system/WebServerSettingsPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" SettingsPageBase { diff --git a/nymea-app/ui/system/WirelessNetworksFilterSettingsPage.qml b/nymea-app/ui/system/WirelessNetworksFilterSettingsPage.qml index 926af868..a3714223 100644 --- a/nymea-app/ui/system/WirelessNetworksFilterSettingsPage.qml +++ b/nymea-app/ui/system/WirelessNetworksFilterSettingsPage.qml @@ -22,13 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.9 -import QtQuick.Layouts 1.2 -import Qt.labs.settings 1.1 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtCore +import Nymea import "qrc:/ui/components" -import Nymea 1.0 Page { id: root diff --git a/nymea-app/ui/system/zigbee/ZigbeeAddNetworkPage.qml b/nymea-app/ui/system/zigbee/ZigbeeAddNetworkPage.qml index 537195d5..32f421d9 100644 --- a/nymea-app/ui/system/zigbee/ZigbeeAddNetworkPage.qml +++ b/nymea-app/ui/system/zigbee/ZigbeeAddNetworkPage.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea import "qrc:/ui/components" diff --git a/nymea-app/ui/system/zigbee/ZigbeeNetworkPage.qml b/nymea-app/ui/system/zigbee/ZigbeeNetworkPage.qml index 5051a658..0d1fe504 100644 --- a/nymea-app/ui/system/zigbee/ZigbeeNetworkPage.qml +++ b/nymea-app/ui/system/zigbee/ZigbeeNetworkPage.qml @@ -22,12 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts import "qrc:/ui/components" -import Nymea 1.0 +import Nymea SettingsPageBase { id: root diff --git a/nymea-app/ui/system/zigbee/ZigbeeNetworkSettingsPage.qml b/nymea-app/ui/system/zigbee/ZigbeeNetworkSettingsPage.qml index 1aed65b3..b7ed6793 100644 --- a/nymea-app/ui/system/zigbee/ZigbeeNetworkSettingsPage.qml +++ b/nymea-app/ui/system/zigbee/ZigbeeNetworkSettingsPage.qml @@ -22,12 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts import "qrc:/ui/components" -import Nymea 1.0 +import Nymea SettingsPageBase { id: root diff --git a/nymea-app/ui/system/zigbee/ZigbeeNetworkTopologyPage.qml b/nymea-app/ui/system/zigbee/ZigbeeNetworkTopologyPage.qml index 392510aa..75802073 100644 --- a/nymea-app/ui/system/zigbee/ZigbeeNetworkTopologyPage.qml +++ b/nymea-app/ui/system/zigbee/ZigbeeNetworkTopologyPage.qml @@ -22,11 +22,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.4 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.1 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "qrc:/ui/components" -import Nymea 1.0 Page { id: root diff --git a/nymea-app/ui/system/zigbee/ZigbeeNodePage.qml b/nymea-app/ui/system/zigbee/ZigbeeNodePage.qml index 0f05fb96..fad26218 100644 --- a/nymea-app/ui/system/zigbee/ZigbeeNodePage.qml +++ b/nymea-app/ui/system/zigbee/ZigbeeNodePage.qml @@ -22,13 +22,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea +import NymeaApp.Utils + import "qrc:/ui/components" -import Nymea 1.0 -import NymeaApp.Utils 1.0 SettingsPageBase { id: root diff --git a/nymea-app/ui/system/zigbee/ZigbeeSettingsPage.qml b/nymea-app/ui/system/zigbee/ZigbeeSettingsPage.qml index 2b6f7131..f170a28f 100644 --- a/nymea-app/ui/system/zigbee/ZigbeeSettingsPage.qml +++ b/nymea-app/ui/system/zigbee/ZigbeeSettingsPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "qrc:/ui/components" -import Nymea 1.0 SettingsPageBase { id: root diff --git a/nymea-app/ui/system/zwave/ZWaveAddNetworkPage.qml b/nymea-app/ui/system/zwave/ZWaveAddNetworkPage.qml index 77a539e4..e25e9ba9 100644 --- a/nymea-app/ui/system/zwave/ZWaveAddNetworkPage.qml +++ b/nymea-app/ui/system/zwave/ZWaveAddNetworkPage.qml @@ -22,10 +22,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea import "../../components" diff --git a/nymea-app/ui/system/zwave/ZWaveNetworkPage.qml b/nymea-app/ui/system/zwave/ZWaveNetworkPage.qml index 8a0af42a..b218027e 100644 --- a/nymea-app/ui/system/zwave/ZWaveNetworkPage.qml +++ b/nymea-app/ui/system/zwave/ZWaveNetworkPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "qrc:/ui/components" -import Nymea 1.0 SettingsPageBase { id: root diff --git a/nymea-app/ui/system/zwave/ZWaveNetworkSettingsPage.qml b/nymea-app/ui/system/zwave/ZWaveNetworkSettingsPage.qml index 29e02a11..19796b5f 100644 --- a/nymea-app/ui/system/zwave/ZWaveNetworkSettingsPage.qml +++ b/nymea-app/ui/system/zwave/ZWaveNetworkSettingsPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "qrc:/ui/components" -import Nymea 1.0 SettingsPageBase { id: root diff --git a/nymea-app/ui/system/zwave/ZWaveSettingsPage.qml b/nymea-app/ui/system/zwave/ZWaveSettingsPage.qml index 68d04efd..6f8edf23 100644 --- a/nymea-app/ui/system/zwave/ZWaveSettingsPage.qml +++ b/nymea-app/ui/system/zwave/ZWaveSettingsPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import Nymea + import "qrc:/ui/components" -import Nymea 1.0 SettingsPageBase { id: root diff --git a/nymea-app/ui/thingconfiguration/ConfigureThingPage.qml b/nymea-app/ui/thingconfiguration/ConfigureThingPage.qml index a3763619..493fa8c0 100644 --- a/nymea-app/ui/thingconfiguration/ConfigureThingPage.qml +++ b/nymea-app/ui/thingconfiguration/ConfigureThingPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../delegates" diff --git a/nymea-app/ui/thingconfiguration/EditThingsPage.qml b/nymea-app/ui/thingconfiguration/EditThingsPage.qml index 78ab65f0..a9930121 100644 --- a/nymea-app/ui/thingconfiguration/EditThingsPage.qml +++ b/nymea-app/ui/thingconfiguration/EditThingsPage.qml @@ -22,12 +22,13 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.4 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.2 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../delegates" -import Nymea 1.0 Page { id: root diff --git a/nymea-app/ui/thingconfiguration/NewThingPage.qml b/nymea-app/ui/thingconfiguration/NewThingPage.qml index 0cf7e36c..87de113d 100644 --- a/nymea-app/ui/thingconfiguration/NewThingPage.qml +++ b/nymea-app/ui/thingconfiguration/NewThingPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Layouts 1.1 -import QtQuick.Controls 2.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Nymea + import "../components" import "../delegates" diff --git a/nymea-app/ui/thingconfiguration/SetupWizard.qml b/nymea-app/ui/thingconfiguration/SetupWizard.qml index 2d062331..e636333e 100644 --- a/nymea-app/ui/thingconfiguration/SetupWizard.qml +++ b/nymea-app/ui/thingconfiguration/SetupWizard.qml @@ -22,11 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.5 -import QtQuick.Layouts 1.1 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import Nymea 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material +import Nymea import "../components" import "../delegates" @@ -532,10 +532,10 @@ Page { property string webViewString: ' - import QtQuick 2.8; - import QtWebView 1.1; - import QtQuick.Controls 2.2 - import Nymea 1.0; + import QtQuick; + import QtWebView; + import QtQuick.Controls + import Nymea; Rectangle { anchors.fill: parent diff --git a/nymea-app/ui/thingconfiguration/ThingClassDetailsPage.qml b/nymea-app/ui/thingconfiguration/ThingClassDetailsPage.qml index b51411f7..fcb70086 100644 --- a/nymea-app/ui/thingconfiguration/ThingClassDetailsPage.qml +++ b/nymea-app/ui/thingconfiguration/ThingClassDetailsPage.qml @@ -22,10 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.2 -import Nymea 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Nymea + import "../components" import "../delegates" diff --git a/nymea-app/ui/utils/ActionQueue.qml b/nymea-app/ui/utils/ActionQueue.qml index ca05ed01..7a4d0d22 100644 --- a/nymea-app/ui/utils/ActionQueue.qml +++ b/nymea-app/ui/utils/ActionQueue.qml @@ -22,8 +22,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import Nymea 1.0 +import QtQuick +import Nymea Item { id: root diff --git a/nymea-app/ui/utils/AirQualityIndex.qml b/nymea-app/ui/utils/AirQualityIndex.qml index b89f1e8e..7c846a85 100644 --- a/nymea-app/ui/utils/AirQualityIndex.qml +++ b/nymea-app/ui/utils/AirQualityIndex.qml @@ -23,8 +23,9 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ pragma Singleton -import QtQuick 2.9 -import Nymea 1.0 + +import QtQuick +import Nymea Item { id: root diff --git a/nymea-app/ui/utils/NymeaUtils.qml b/nymea-app/ui/utils/NymeaUtils.qml index 783850d3..daec4ae7 100644 --- a/nymea-app/ui/utils/NymeaUtils.qml +++ b/nymea-app/ui/utils/NymeaUtils.qml @@ -23,9 +23,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ pragma Singleton -import QtQuick 2.9 -import Nymea 1.0 -import QtCharts 2.2 + +import QtQuick +import Nymea +import QtCharts Item { id: root diff --git a/packaging/android/AndroidManifest.xml b/packaging/android/AndroidManifest.xml index fec56141..e242d9ea 100644 --- a/packaging/android/AndroidManifest.xml +++ b/packaging/android/AndroidManifest.xml @@ -1,141 +1,95 @@ - + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -149,11 +103,6 @@ - - - - - - - - - - - - diff --git a/packaging/android/build.gradle b/packaging/android/build.gradle index f2e95a3e..16e86bd3 100644 --- a/packaging/android/build.gradle +++ b/packaging/android/build.gradle @@ -12,6 +12,7 @@ buildscript { repositories { jcenter() google() + mavenCentral() } dependencies { @@ -33,10 +34,10 @@ allprojects { } } -apply plugin: 'com.android.application' +apply plugin: qtGradlePluginType dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) implementation 'org.reactivestreams:reactive-streams:1.0.3' implementation 'io.reactivex.rxjava2:rxjava:2.2.0' implementation 'androidx.core:core:1.16.0' @@ -61,50 +62,58 @@ android { * The following variables: * - androidBuildToolsVersion, * - androidCompileSdkVersion - * - qt5AndroidDir - holds the path to qt android files + * - qtAndroidDir - holds the path to qt android files * needed to build any Qt application * on Android. + * - qtGradlePluginType - whether to build an app or a library * * are defined in gradle.properties file. This file is * updated by QtCreator and androiddeployqt tools. * Changing them manually might break the compilation! *******************************************************/ - compileSdkVersion androidCompileSdkVersion.toInteger() - buildToolsVersion androidBuildToolsVersion - namespace 'io.guh.nymeaapp' - buildFeatures.aidl = true + compileSdkVersion androidCompileSdkVersion + buildToolsVersion androidBuildToolsVersion + ndkVersion androidNdkVersion - packagingOptions { - jniLibs { - useLegacyPackaging = true - } - } + // Extract native libraries from the APK + packagingOptions.jniLibs.useLegacyPackaging true sourceSets { main { manifest.srcFile 'AndroidManifest.xml' - java.srcDirs = [ - qt5AndroidDir + '/src', - nymeaAppRoot + '/androidservice/java', - nymeaAppRoot + '/nymea-app/platformintegration/android/java', - nymeaAppRoot + '/QtZeroConf/android', - 'src', - 'java'] - if ("${useFirebase}" == "true") { - java.srcDirs += [nymeaAppRoot + '/nymea-app/platformintegration/android/java-firebase'] - } - - aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl'] - res.srcDirs = [qt5AndroidDir + '/res', 'res'] + java.srcDirs = [qtAndroidDir + '/src', 'src', 'java'] + aidl.srcDirs = [qtAndroidDir + '/src', 'src', 'aidl'] + res.srcDirs = [qtAndroidDir + '/res', 'res'] resources.srcDirs = ['src'] renderscript.srcDirs = ['src'] assets.srcDirs = ['assets'] jniLibs.srcDirs = ['libs'] + + java.srcDirs = [ + qt5AndroidDir + '/src', + nymeaAppRoot + '/nymea-app/platformintegration/android/java', + nymeaAppRoot + '/QtZeroConf/android', + 'src', + 'java'] + + if ("${useFirebase}" == "true") { + java.srcDirs += [nymeaAppRoot + '/nymea-app/platformintegration/android/java-firebase'] + } + } } + tasks.withType(JavaCompile) { + options.incremental = true + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + lintOptions { abortOnError false } diff --git a/packaging/android/gradle/wrapper/gradle-wrapper.properties b/packaging/android/gradle/wrapper/gradle-wrapper.properties index 2733ed5d..37f853b1 100644 --- a/packaging/android/gradle/wrapper/gradle-wrapper.properties +++ b/packaging/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packaging/android/res/values/libs.xml b/packaging/android/res/values/libs.xml index 1437232f..fe63866f 100644 --- a/packaging/android/res/values/libs.xml +++ b/packaging/android/res/values/libs.xml @@ -1,29 +1,21 @@ - - https://download.qt.io/ministro/android/qt5/qt-5.8 - - - + - - - - - - - - - + + + + + + diff --git a/packaging/android/res/values/styles.xml b/packaging/android/res/values/styles.xml new file mode 100644 index 00000000..8873ed76 --- /dev/null +++ b/packaging/android/res/values/styles.xml @@ -0,0 +1,6 @@ + + + + diff --git a/packaging/android/res/xml/qtprovider_paths.xml b/packaging/android/res/xml/qtprovider_paths.xml new file mode 100644 index 00000000..3488bf27 --- /dev/null +++ b/packaging/android/res/xml/qtprovider_paths.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/packaging/ubuntu/debian-qt5/changelog b/packaging/ubuntu/debian-qt5/changelog new file mode 100644 index 00000000..4e2b16e1 --- /dev/null +++ b/packaging/ubuntu/debian-qt5/changelog @@ -0,0 +1,4125 @@ +nymea-app (1.10.13) bionic; urgency=medium + + [ Simon Stürz ] + * Android: fix keyboard margins + + -- jenkins Tue, 23 Sep 2025 15:15:25 +0200 + +nymea-app (1.10.12) bionic; urgency=medium + + [ Simon Stürz ] + * Add power balance pi chart icon properties + + -- jenkins Tue, 22 Jul 2025 09:48:45 +0200 + +nymea-app (1.10.11) bionic; urgency=medium + + [ Simon Stürz ] + * Use Qt 5.12 as highest Qt version in QML + + -- jenkins Mon, 21 Jul 2025 10:40:17 +0200 + +nymea-app (1.10.8) bionic; urgency=medium + + [ Simon Stürz ] + * Add material icons and make icon set exchangable + + -- jenkins Mon, 14 Jul 2025 14:24:57 +0200 + +nymea-app (1.10.2) bionic; urgency=medium + + [ Simon Stürz ] + * Bump build number + + -- jenkins Fri, 09 May 2025 12:04:43 +0200 + +nymea-app (1.10.1) bionic; urgency=medium + + [ Simon Stürz ] + * Rework overlay + + -- jenkins Tue, 06 May 2025 15:46:15 +0200 + +nymea-app (1.9.22) bionic; urgency=medium + + [ Simon Stürz ] + * Add device code oauth handling + + -- jenkins Sat, 29 Mar 2025 23:11:19 +0100 + +nymea-app (1.9.21) bionic; urgency=medium + + [ Simon Stürz ] + * Remove deprecated forum link + + -- jenkins Thu, 30 Jan 2025 16:54:56 +0100 + +nymea-app (1.9.20) bionic; urgency=medium + + [ Simon Stürz ] + * Prevent unlocking yourself as admin user + + -- jenkins Thu, 30 Jan 2025 10:46:59 +0100 + +nymea-app (1.9.18) bionic; urgency=medium + + [ Simon Stürz ] + * Add additional imprint links + + -- jenkins Thu, 16 Jan 2025 14:09:09 +0100 + +nymea-app (1.9.17) bionic; urgency=medium + + [ Simon Stürz ] + * Bump version + + -- jenkins Tue, 14 Jan 2025 11:01:20 +0100 + +nymea-app (1.9.16) bionic; urgency=medium + + [ Simon Stürz ] + * Bump version to 1.9.16 + + -- jenkins Tue, 14 Jan 2025 09:48:22 +0100 + +nymea-app (1.9.15) bionic; urgency=medium + + [ Simon Stürz ] + * Add server debug JSON RPC functionality + + -- jenkins Fri, 20 Dec 2024 15:30:33 +0100 + +nymea-app (1.9.14) bionic; urgency=medium + + [ Simon Stürz ] + * Fix multisection tabs font + + -- jenkins Tue, 26 Nov 2024 16:36:23 +0100 + +nymea-app (1.9.13) bionic; urgency=medium + + [ Simon Stürz ] + * Bump version + + -- jenkins Tue, 12 Nov 2024 15:05:55 +0100 + +nymea-app (1.9.12) bionic; urgency=medium + + [ Simon Stürz ] + * Adapt links to online privacy policy through configuration parameter + + -- jenkins Fri, 25 Oct 2024 11:33:31 +0200 + +nymea-app (1.9.11) bionic; urgency=medium + + [ Simon Stürz ] + * Clean up host information propertly once removed from settings + * Add wireless capabilities and disable wireless AP setting if not + capable + + -- jenkins Thu, 24 Oct 2024 16:36:07 +0200 + +nymea-app (1.9.10) bionic; urgency=medium + + [ Simon Stürz ] + * Update nymea-remoteproxy submodule + + -- jenkins Tue, 01 Oct 2024 15:41:25 +0200 + +nymea-app (1.9.9) bionic; urgency=medium + + [ Simon Stürz ] + * Add wifi networks filter duplicates option + + -- jenkins Mon, 16 Sep 2024 15:29:10 +0200 + +nymea-app (1.9.8) bionic; urgency=medium + + [ martinlukas84 ] + * Introduce overview for states and events of things + + -- jenkins Tue, 10 Sep 2024 16:20:28 +0200 + +nymea-app (1.9.7) bionic; urgency=medium + + [ Simon Stürz ] + * Android: Update to firebase SDK 12.2.0 + + -- jenkins Mon, 09 Sep 2024 17:07:24 +0200 + +nymea-app (1.9.6) bionic; urgency=medium + + [ martinlukas84 ] + * Update Aboutpage regarding the licence term + + -- jenkins Fri, 06 Sep 2024 12:28:31 +0200 + +nymea-app (1.9.5) bionic; urgency=medium + + [ Simon Stürz ] + * Update to gradle 8 and android SDK 34 + + -- jenkins Thu, 05 Sep 2024 22:43:38 +0200 + +nymea-app (1.9.3) bionic; urgency=medium + + [ Simon Stürz ] + * Update translations + + -- jenkins Wed, 04 Sep 2024 21:27:51 +0200 + +nymea-app (1.9.2) bionic; urgency=medium + + [ Simon Stürz ] + * Update tunnel proy configuration and german translation + + -- jenkins Thu, 29 Aug 2024 12:15:19 +0200 + +nymea-app (1.9.1) bionic; urgency=medium + + [ Simon Stürz ] + * Update gradl and android firbease SDK and GCM notification handling + + -- jenkins Wed, 24 Jul 2024 08:39:47 +0200 + +nymea-app (1.8.44) bionic; urgency=medium + + [ Simon Stürz ] + * Introduce font scaling mechanism + + -- jenkins Thu, 11 Jul 2024 09:11:33 +0200 + +nymea-app (1.8.43) bionic; urgency=medium + + [ Simon Stürz ] + * Update translations and company name + + -- jenkins Mon, 17 Jun 2024 12:36:06 +0200 + +nymea-app (1.8.42) bionic; urgency=medium + + [ Simon Stürz ] + * Update translations and fix german typos + + -- jenkins Thu, 13 Jun 2024 17:25:38 +0200 + +nymea-app (1.8.40) bionic; urgency=medium + + [ Simon Stürz ] + * Remove deprecated documentations and links + + -- jenkins Tue, 04 Jun 2024 15:50:40 +0200 + +nymea-app (1.8.38) bionic; urgency=medium + + [ Michael Zanetti ] + * Add Timer::restart() to script code completion + * Some layout fixes in the Sensor page + + -- jenkins Tue, 14 May 2024 11:19:09 +0200 + +nymea-app (1.8.37) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix kiosk systemd target + + -- jenkins Mon, 01 Jan 2024 22:39:08 +0100 + +nymea-app (1.8.36) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix removing window sensors in AC settings + + -- jenkins Sun, 31 Dec 2023 13:56:22 +0100 + +nymea-app (1.8.35) bionic; urgency=medium + + [ Michael Zanetti ] + * New thing status view + + -- jenkins Sun, 31 Dec 2023 12:43:49 +0100 + +nymea-app (1.8.33) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix ordering of live entries in logs + + -- jenkins Fri, 29 Dec 2023 14:13:29 +0100 + +nymea-app (1.8.31) bionic; urgency=medium + + [ Michael Zanetti ] + * Only handle things as disconnected when they implement the + connectable interface + * Add copy to clipboard action to generic state delegates + * Improve ScriptEditor zoom keyboard keys + + -- jenkins Tue, 28 Nov 2023 09:06:03 +0100 + +nymea-app (1.8.30) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix bool charts after inverting them + + -- jenkins Fri, 20 Oct 2023 23:33:55 +0200 + +nymea-app (1.8.29) bionic; urgency=medium + + [ Michael Zanetti ] + * Invert state chart painting + + -- jenkins Tue, 17 Oct 2023 23:02:40 +0200 + +nymea-app (1.8.28) bionic; urgency=medium + + [ Daniel Frost ] + * fix typo dden to den + + -- jenkins Sat, 14 Oct 2023 22:01:18 +0200 + +nymea-app (1.8.27) bionic; urgency=medium + + [ Michael Zanetti ] + * Allow editing rule exitActions + + -- jenkins Sat, 14 Oct 2023 20:42:58 +0200 + +nymea-app (1.8.26) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix sensor list page delegate updating + * Fix Button event view + + -- jenkins Sat, 14 Oct 2023 13:36:24 +0200 + +nymea-app (1.8.25) bionic; urgency=medium + + [ Michael Zanetti ] + * Make dashboard wizard usable on small screens + * Update translations and complete german translation + * Add dashboard sensor delegate support + + -- jenkins Wed, 11 Oct 2023 23:59:08 +0200 + +nymea-app (1.8.24) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix interface icon for update interface + + -- jenkins Wed, 11 Oct 2023 22:46:02 +0200 + +nymea-app (1.8.23) bionic; urgency=medium + + [ Michael Zanetti ] + * Ubuntu touch 20.04 + + -- jenkins Tue, 03 Oct 2023 12:49:02 +0200 + +nymea-app (1.8.22) bionic; urgency=medium + + [ Michael Zanetti ] + * Add dashboard state delegate + * Fix some issues with logs + + -- jenkins Thu, 21 Sep 2023 09:55:21 +0200 + +nymea-app (1.8.21) bionic; urgency=medium + + [ Michael Zanetti ] + * Add czech translation + * Remove debug print leftover + + -- jenkins Thu, 07 Sep 2023 15:42:57 +0200 + +nymea-app (1.8.20) bionic; urgency=medium + + [ Michael Zanetti ] + * Add a confirmation dialog when removing hosts + + -- jenkins Fri, 01 Sep 2023 12:37:02 +0200 + +nymea-app (1.8.19) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix SSL enabled checkbox when editing a tunnel proxy connection + + -- jenkins Mon, 03 Jul 2023 17:34:08 +0200 + +nymea-app (1.8.18) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for dynamic and localized possibleValues on states + + -- jenkins Wed, 28 Jun 2023 12:44:15 +0200 + +nymea-app (1.8.17) bionic; urgency=medium + + [ alpha-rd ] + * Dutch translation ready + + -- jenkins Thu, 22 Jun 2023 19:20:52 +0200 + +nymea-app (1.8.16) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix paramdelegate for editing rules + + -- jenkins Wed, 21 Jun 2023 20:13:57 +0200 + +nymea-app (1.8.15) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve param delegates + + -- jenkins Mon, 19 Jun 2023 16:02:19 +0200 + +nymea-app (1.8.14) bionic; urgency=medium + + [ Michael Zanetti ] + * Replace some Android support.v4 with androidx libraries + + -- jenkins Tue, 13 Jun 2023 19:32:25 +0200 + +nymea-app (1.8.13) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve charts axis labels for small value states + + -- jenkins Sun, 11 Jun 2023 19:43:35 +0200 + +nymea-app (1.8.12) bionic; urgency=medium + + [ Michael Zanetti ] + * Add code completion for action executed events + + -- jenkins Wed, 07 Jun 2023 14:53:34 +0200 + +nymea-app (1.8.11) bionic; urgency=medium + + [ Michael Zanetti ] + * Remove old logs view from the thing context menu + * Disable dashboard longpress editmode + + -- jenkins Tue, 06 Jun 2023 21:17:44 +0200 + +nymea-app (1.8.10) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix dashboard charts title for non-numeric states + + -- jenkins Tue, 06 Jun 2023 14:45:54 +0200 + +nymea-app (1.8.9) bionic; urgency=medium + + [ alpha-rd ] + * Update nymea-app.nl.ts + + -- jenkins Thu, 01 Jun 2023 11:41:38 +0200 + +nymea-app (1.8.8) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve rules editor + + -- jenkins Wed, 31 May 2023 10:31:59 +0200 + +nymea-app (1.8.7) bionic; urgency=medium + + [ pop-ch ] + * Update nymea-app.de.ts + + -- jenkins Tue, 30 May 2023 13:08:04 +0200 + +nymea-app (1.8.6) bionic; urgency=medium + + [ Michael Zanetti ] + * Drop old unused cloudEnabled settings + + -- jenkins Thu, 25 May 2023 12:44:22 +0200 + +nymea-app (1.8.5) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve group editing popup + * Elide labels in Selection tabs + + -- jenkins Wed, 24 May 2023 20:02:13 +0200 + +nymea-app (1.8.4) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix import in AC view + + -- jenkins Sat, 20 May 2023 23:30:05 +0200 + +nymea-app (1.8.3) bionic; urgency=medium + + [ Michael Zanetti ] + * Hide ac admin options for users + * Fix popup being cut off in AC time scehdule editor + + -- jenkins Sat, 20 May 2023 13:11:18 +0200 + +nymea-app (1.8.2) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix value axis labels for negative values in StateChart + + -- jenkins Thu, 18 May 2023 12:19:56 +0200 + +nymea-app (1.8.1) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve action/event log views when there's no data yet + + -- jenkins Wed, 17 May 2023 11:58:48 +0200 + +nymea-app (1.8.0) bionic; urgency=medium + + [ Michael Zanetti ] + * Bump version to 1.8 + + -- jenkins Tue, 16 May 2023 12:48:49 +0200 + +nymea-app (1.7.23) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix icon on missig AC plugin placeholder message + + -- jenkins Tue, 16 May 2023 11:04:37 +0200 + +nymea-app (1.7.20) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix new charts for older Qt versions + + -- jenkins Wed, 10 May 2023 23:19:50 +0200 + +nymea-app (1.7.19) bionic; urgency=medium + + [ Danfro ] + * add build folder to .gitignore + * fix typo thigns to things + + -- jenkins Wed, 10 May 2023 22:38:47 +0200 + +nymea-app (1.7.18) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix a missing changed signal in AC settings + + -- jenkins Tue, 09 May 2023 09:12:44 +0200 + +nymea-app (1.7.17) bionic; urgency=medium + + [ Michael Zanetti ] + * Update android's libssl to latest version + + -- jenkins Mon, 08 May 2023 17:09:18 +0200 + +nymea-app (1.7.16) bionic; urgency=medium + + [ Michael Zanetti ] + * Add a confirmation question when removing a thing + + -- jenkins Mon, 08 May 2023 15:58:20 +0200 + +nymea-app (1.7.15) bionic; urgency=medium + + [ Michael Zanetti ] + * Update translations + * Improve tooltips in new charts + + -- jenkins Mon, 08 May 2023 00:33:00 +0200 + +nymea-app (1.7.14) bionic; urgency=medium + + [ Michael Zanetti ] + * Use a ComboBox for number states with allowedValues + + -- jenkins Wed, 03 May 2023 19:27:16 +0200 + +nymea-app (1.7.13) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix scrolling by touch in AC charts + * Adjust repeat combobox width when creating a rule + + -- jenkins Wed, 03 May 2023 07:54:44 +0200 + +nymea-app (1.7.12) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve ac charts + + -- jenkins Tue, 02 May 2023 01:17:27 +0200 + +nymea-app (1.7.11) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve new logs integration further + + -- jenkins Wed, 26 Apr 2023 23:46:36 +0200 + +nymea-app (1.7.10) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve new logging stuff further + + -- jenkins Tue, 25 Apr 2023 00:01:05 +0200 + +nymea-app (1.7.9) bionic; urgency=medium + + [ Michael Zanetti ] + * More work on the new logs + + -- jenkins Mon, 24 Apr 2023 11:39:35 +0200 + +nymea-app (1.7.8) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix dashboard chart item for legacy charts + + -- jenkins Thu, 20 Apr 2023 14:22:50 +0200 + +nymea-app (1.7.7) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for the new log engine (protocol version 8.0) + + -- jenkins Wed, 19 Apr 2023 12:27:56 +0200 + +nymea-app (1.7.6) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix the script editor breaking when trying to add a new script with + errors + + -- jenkins Sun, 09 Apr 2023 23:51:34 +0200 + +nymea-app (1.7.5) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix removing a zigbee node from within the nodes view + + -- jenkins Fri, 07 Apr 2023 13:17:33 +0200 + +nymea-app (1.7.4) bionic; urgency=medium + + [ Michael Zanetti ] + * Handle inline controls for virtual switch and button + * Add WindowCovering zigbee cluster id + + -- jenkins Tue, 04 Apr 2023 19:47:35 +0200 + +nymea-app (1.7.3) bionic; urgency=medium + + [ Michael Zanetti ] + * Optimize loading performance of the energy history charts + + -- jenkins Thu, 30 Mar 2023 09:41:03 +0200 + +nymea-app (1.7.2) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix a typo in german translation + * Add a find() method to SerialPorts + + -- jenkins Tue, 28 Mar 2023 19:53:28 +0200 + +nymea-app (1.7.1) bionic; urgency=medium + + [ Michael Zanetti ] + * Hide user admin settings for unprivileged users + * Fix overlapping views at startup + * Allow overriding the IOS_TEAM_ID + * Change how translations are loaded + + -- jenkins Sat, 18 Mar 2023 01:06:25 +0100 + +nymea-app (1.7.0) bionic; urgency=medium + + [ Michael Zanetti ] + * Ignore return code 3010 from vcredist package. + * Bump version to 1.7 + + -- jenkins Thu, 09 Mar 2023 23:19:56 +0100 + +nymea-app (1.6.31) bionic; urgency=medium + + [ Michael Zanetti ] + * Allow styling energy colors + * Allow styling of tabbar icon color + * Fix color picker for interface based rule action + + -- jenkins Thu, 09 Mar 2023 12:52:25 +0100 + +nymea-app (1.6.29) bionic; urgency=medium + + [ Michael Zanetti ] + * Update translations + + -- jenkins Wed, 08 Mar 2023 09:34:57 +0100 + +nymea-app (1.6.28) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix the main menus remove buttons being clickable when hidden + + -- jenkins Fri, 03 Mar 2023 12:15:57 +0100 + +nymea-app (1.6.27) bionic; urgency=medium + + [ Michael Zanetti ] + * Hide outdoor sensor settings in AC settings + * Fix ac charts also showing actions + + -- jenkins Thu, 02 Mar 2023 23:31:36 +0100 + +nymea-app (1.6.26) bionic; urgency=medium + + [ Michael Zanetti ] + * Switch to demo server with authentication + + -- jenkins Mon, 27 Feb 2023 00:49:40 +0100 + +nymea-app (1.6.25) bionic; urgency=medium + + [ Michael Zanetti ] + * Support notification alerts for air conditioning + * Don't show a positive currentPower for producers in thing page + * Make the producer visible when there's return + + -- jenkins Sat, 25 Feb 2023 23:18:46 +0100 + +nymea-app (1.6.24) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix power balance chart when there's returned energy but no producer + + -- jenkins Wed, 22 Feb 2023 17:43:11 +0100 + +nymea-app (1.6.23) bionic; urgency=medium + + [ Michael Zanetti ] + * Add PrivacyPolicyHelper + + -- jenkins Mon, 20 Feb 2023 12:33:50 +0100 + +nymea-app (1.6.22) bionic; urgency=medium + + [ Michael Zanetti ] + * Add more sensor delegates to ZoneView and allow opening the thing + view + + -- jenkins Sat, 18 Feb 2023 12:43:24 +0100 + +nymea-app (1.6.20) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix selection in power balance history + + -- jenkins Thu, 16 Feb 2023 19:25:03 +0100 + +nymea-app (1.6.18) bionic; urgency=medium + + [ Michael Zanetti ] + * Rework overlay mechanism + + -- jenkins Tue, 14 Feb 2023 17:51:00 +0100 + +nymea-app (1.6.16) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix energy charts with old Qt versions + + -- jenkins Tue, 14 Feb 2023 14:27:28 +0100 + +nymea-app (1.6.15) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix close button in main menu to remove a connection + * Improve wording for unknown error + * Fix working in rules param condition selectors + + -- jenkins Mon, 13 Feb 2023 15:06:58 +0100 + +nymea-app (1.6.14) bionic; urgency=medium + + [ Michael Zanetti ] + * Some fixes for older Qt versions + + -- jenkins Sun, 12 Feb 2023 23:07:29 +0100 + +nymea-app (1.6.13) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix calculation of zone temperature in certain circumstances + + -- jenkins Sun, 12 Feb 2023 22:11:17 +0100 + +nymea-app (1.6.12) bionic; urgency=medium + + [ Michael Zanetti ] + * Allow ordering the hosts list + + -- jenkins Sun, 12 Feb 2023 00:34:54 +0100 + +nymea-app (1.6.11) bionic; urgency=medium + + [ Michael Zanetti ] + * Add air conditioning experience + + -- jenkins Sat, 11 Feb 2023 22:18:23 +0100 + +nymea-app (1.6.10) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix network settings appearing to freeze on errors + + -- jenkins Wed, 08 Feb 2023 19:47:28 +0100 + +nymea-app (1.6.9) bionic; urgency=medium + + [ Michael Zanetti ] + * more iOS reachabilitty tuning + + -- jenkins Fri, 27 Jan 2023 14:32:51 +0100 + +nymea-app (1.6.8) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix frequent reconnects on iOS + * Fix energy chargs legend opacity when single items are selected + + -- jenkins Wed, 25 Jan 2023 22:50:22 +0100 + +nymea-app (1.6.5) bionic; urgency=medium + + [ Michael Zanetti ] + * Enable building on riscv64 + * Fix webview not working in the snap package + + -- jenkins Wed, 25 Jan 2023 15:49:58 +0100 + +nymea-app (1.6.4) bionic; urgency=medium + + [ Michael Zanetti ] + * Hide install more plugins hint when the system does not support it + + -- jenkins Tue, 17 Jan 2023 20:12:53 +0100 + +nymea-app (1.6.3) bionic; urgency=medium + + [ Michael Zanetti ] + * Suggest to install more plugins in add things page + + -- jenkins Sun, 15 Jan 2023 20:27:32 +0100 + +nymea-app (1.6.2) bionic; urgency=medium + + [ Michael Zanetti ] + * Specify some base interfaces for better grouping + * Fix energy return in chart when there are no producers + * cleanup runtime debug prints + * Drop connection tabs support + * Move utils into separate module + + -- jenkins Sun, 15 Jan 2023 10:51:41 +0100 + +nymea-app (1.6.1) bionic; urgency=medium + + [ Michael Zanetti ] + * Make energy logs more robust against faulty databases + * Fix rule action param editor with value from state + + -- jenkins Thu, 22 Dec 2022 14:47:13 +0100 + +nymea-app (1.6.0) bionic; urgency=medium + + [ Michael Zanetti ] + * Bump version + + -- jenkins Mon, 19 Dec 2022 11:28:45 +0100 + +nymea-app (1.5.23) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve managing of manual connections + + -- jenkins Fri, 16 Dec 2022 15:51:47 +0100 + +nymea-app (1.5.22) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix a crash with checking location permissions on old androids + * Fix some permission backwards compatibility issues with older + android versions + * Fix firebase libs for android x86 + + -- jenkins Thu, 15 Dec 2022 14:58:31 +0100 + +nymea-app (1.5.21) bionic; urgency=medium + + [ Michael Zanetti ] + * Update translations + + -- jenkins Mon, 12 Dec 2022 11:53:37 +0100 + +nymea-app (1.5.20) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix bluetooth permission checking for android <= 30 (11) + + -- jenkins Fri, 09 Dec 2022 15:29:51 +0100 + +nymea-app (1.5.19) bionic; urgency=medium + + [ Michael Zanetti ] + * Refresh notification permission on iOS when the app is focused + + -- jenkins Thu, 08 Dec 2022 16:31:30 +0100 + +nymea-app (1.5.18) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix some glitches in energy chats if the user changes the time zone + + -- jenkins Thu, 08 Dec 2022 00:24:37 +0100 + +nymea-app (1.5.17) bionic; urgency=medium + + [ Michael Zanetti ] + * Add NSLocationAlwaysAndWhenInUseUsageDescription declaration for iOS + + -- jenkins Wed, 07 Dec 2022 21:25:22 +0100 + +nymea-app (1.5.16) bionic; urgency=medium + + [ Michael Zanetti ] + * Add a check for location services being enabled in BtWiFi setup + + -- jenkins Wed, 07 Dec 2022 20:19:13 +0100 + +nymea-app (1.5.15) bionic; urgency=medium + + [ Michael Zanetti ] + * Ignore error code 1638 in win installer for the vc_redist package + + -- jenkins Wed, 07 Dec 2022 14:42:22 +0100 + +nymea-app (1.5.14) bionic; urgency=medium + + [ Michael Zanetti ] + * Add vibration sensor interface + + -- jenkins Wed, 07 Dec 2022 00:29:29 +0100 + +nymea-app (1.5.13) bionic; urgency=medium + + [ Michael Zanetti ] + * Drop AWS cloud support + + -- jenkins Fri, 02 Dec 2022 12:15:25 +0100 + +nymea-app (1.5.12) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix energy canvas scaling problems on iOS + + -- jenkins Fri, 02 Dec 2022 00:21:40 +0100 + +nymea-app (1.5.11) bionic; urgency=medium + + [ Michael Zanetti ] + * Add ios location permission declaration + + -- jenkins Mon, 28 Nov 2022 16:28:28 +0100 + +nymea-app (1.5.10) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix bluetooth permission on android + * Add ubuntu mono font + + -- jenkins Mon, 28 Nov 2022 15:36:20 +0100 + +nymea-app (1.5.9) bionic; urgency=medium + + [ Michael Zanetti ] + * More improvements on the energy view + * Add MultiSelectionTabs component + + -- jenkins Sat, 26 Nov 2022 01:30:33 +0100 + +nymea-app (1.5.8) bionic; urgency=medium + + [ Michael Zanetti ] + * Fixes on unified energy charts + + -- jenkins Wed, 23 Nov 2022 12:28:51 +0100 + +nymea-app (1.5.7) bionic; urgency=medium + + [ Michael Zanetti ] + * Some fixes in the platform permission helper for android + + -- jenkins Tue, 22 Nov 2022 14:08:31 +0100 + +nymea-app (1.5.6) bionic; urgency=medium + + [ Michael Zanetti ] + * Tweak rendering performance for power balance animation + + -- jenkins Mon, 21 Nov 2022 01:00:35 +0100 + +nymea-app (1.5.5) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix crash in the connectionwizard on android (requesting + localnetwork permission) + + -- jenkins Sun, 20 Nov 2022 22:02:57 +0100 + +nymea-app (1.5.4) bionic; urgency=medium + + [ Michael Zanetti ] + * Update permission handling + + -- jenkins Sun, 20 Nov 2022 19:57:11 +0100 + +nymea-app (1.5.3) bionic; urgency=medium + + [ Michael Zanetti ] + * Bump android api level to 31 + * Unified energy charts + + -- jenkins Sat, 19 Nov 2022 12:49:47 +0100 + +nymea-app (1.5.2) bionic; urgency=medium + + [ Michael Zanetti ] + * Add total values to energy device pages + * Fix settings page for Qt 5.9 + * Fix dial not using dynamic max value + * Fix a race condition in initializing the android service + * Add support for the childlock interface + + -- jenkins Sat, 19 Nov 2022 01:09:06 +0100 + +nymea-app (1.5.1) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix energy charts when DST changes + + -- jenkins Tue, 01 Nov 2022 12:45:31 +0100 + +nymea-app (1.5.0) bionic; urgency=medium + + [ Michael Zanetti ] + * Bump version to 1.5 + + -- jenkins Tue, 25 Oct 2022 11:04:18 +0200 + +nymea-app (1.4.29) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix NymeaUtils.pad() regression + + -- jenkins Thu, 20 Oct 2022 21:24:52 +0200 + +nymea-app (1.4.28) bionic; urgency=medium + + [ Michael Zanetti ] + * Update translations + + -- jenkins Thu, 20 Oct 2022 14:55:22 +0200 + +nymea-app (1.4.27) bionic; urgency=medium + + [ Michael Zanetti ] + * Zigbee cleanup + * Fix energy consumers history sometimes not loading when a filter is + set + + -- jenkins Wed, 19 Oct 2022 23:16:27 +0200 + +nymea-app (1.4.26) bionic; urgency=medium + + [ Michael Zanetti ] + * Align various sensor displays + + -- jenkins Mon, 17 Oct 2022 23:37:59 +0200 + +nymea-app (1.4.25) bionic; urgency=medium + + [ Michael Zanetti ] + * More air quality sensors + * Fix style of media browser header + * Add support for wired network configuration + + -- jenkins Tue, 11 Oct 2022 09:12:08 +0200 + +nymea-app (1.4.24) bionic; urgency=medium + + [ Michael Zanetti ] + * Show serial port name when adding a zwave network + * Fix a typo in the german translation + * Send last queued command in an actionqueue on destruction + * Update gas interface + + -- jenkins Mon, 03 Oct 2022 01:45:53 +0200 + +nymea-app (1.4.23) bionic; urgency=medium + + [ Michael Zanetti ] + * Add code completion for new script things + + -- jenkins Sun, 25 Sep 2022 01:26:04 +0200 + +nymea-app (1.4.22) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix placeholder replacement for interface based rule templates + * Fix things info for Zigbee nodes with multiple things + * Another fix for the energy tooltips + * Fix occational duplicate entries in consumer stats + + -- jenkins Sat, 24 Sep 2022 13:28:44 +0200 + +nymea-app (1.4.21) bionic; urgency=medium + + [ Michael Zanetti ] + * Allow binding all clusters to the coordinator + * Fix params for actions in the generic log page + + -- jenkins Wed, 21 Sep 2022 16:02:05 +0200 + +nymea-app (1.4.20) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for Android themed icons + + -- jenkins Tue, 20 Sep 2022 01:10:33 +0200 + +nymea-app (1.4.19) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix destination node selection for Zigbee bindings + * Re-enable energy charts + + -- jenkins Fri, 16 Sep 2022 00:44:07 +0200 + +nymea-app (1.4.18) bionic; urgency=medium + + [ Michael Zanetti ] + * Fixes for the energy dashboard for various corner cases + + -- jenkins Thu, 15 Sep 2022 17:45:30 +0200 + +nymea-app (1.4.17) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for configuring ZigBee bindings + + -- jenkins Wed, 14 Sep 2022 23:48:59 +0200 + +nymea-app (1.4.16) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix zigbee topology map pinch area + + -- jenkins Sun, 11 Sep 2022 13:11:58 +0200 + +nymea-app (1.4.15) bionic; urgency=medium + + [ Michael Zanetti ] + * Optimizations and pinch scaling for Zigbee topology map + + -- jenkins Sun, 11 Sep 2022 01:41:40 +0200 + +nymea-app (1.4.14) bionic; urgency=medium + + [ Michael Zanetti ] + * More fixes in the Zigbee Topology map + + -- jenkins Sat, 10 Sep 2022 10:52:15 +0200 + +nymea-app (1.4.13) bionic; urgency=medium + + [ Michael Zanetti ] + * Improvements in the ZigBee topology map + + -- jenkins Fri, 09 Sep 2022 00:51:46 +0200 + +nymea-app (1.4.12) bionic; urgency=medium + + [ Michael Zanetti ] + * Fixes for the network reachaiblity monitor + + -- jenkins Thu, 08 Sep 2022 00:35:51 +0200 + +nymea-app (1.4.11) bionic; urgency=medium + + [ Michael Zanetti ] + * Add ZigBee routing information to topology map + + -- jenkins Wed, 07 Sep 2022 12:36:11 +0200 + +nymea-app (1.4.10) bionic; urgency=medium + + [ Michael Zanetti ] + * Add more debug prints to network reachability monitor + + -- jenkins Tue, 06 Sep 2022 19:45:32 +0200 + +nymea-app (1.4.9) bionic; urgency=medium + + [ Michael Zanetti ] + * Replace QNetworkworkConfiguration with Reachability API on iOS + + -- jenkins Tue, 06 Sep 2022 13:29:03 +0200 + +nymea-app (1.4.8) bionic; urgency=medium + + [ Michael Zanetti ] + * Some improvements in the zigbee topology map + + -- jenkins Mon, 05 Sep 2022 19:11:34 +0200 + +nymea-app (1.4.7) bionic; urgency=medium + + [ Michael Zanetti ] + * More fixes in scrollable energy charts + + -- jenkins Sun, 04 Sep 2022 22:03:55 +0200 + +nymea-app (1.4.6) bionic; urgency=medium + + [ Michael Zanetti ] + * Add a zigbee network topology map + + -- jenkins Sat, 03 Sep 2022 02:13:08 +0200 + +nymea-app (1.4.5) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix tooltips in energy charts + * Fix setup status warning not always updating in ThingsView + + -- jenkins Fri, 02 Sep 2022 15:57:52 +0200 + +nymea-app (1.4.4) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for connecting to hidden wifi networks during bt wifi + setup + + -- jenkins Thu, 01 Sep 2022 17:36:26 +0200 + +nymea-app (1.4.3) bionic; urgency=medium + + [ Michael Zanetti ] + * Make the energy charts scrollable + + -- jenkins Tue, 30 Aug 2022 16:55:42 +0200 + +nymea-app (1.4.2) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix zwave device info data + + -- jenkins Sat, 27 Aug 2022 13:56:47 +0200 + +nymea-app (1.4.1) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix Z-Wave security mode display + + -- jenkins Fri, 26 Aug 2022 01:01:09 +0200 + +nymea-app (1.4.0) bionic; urgency=medium + + [ Michael Zanetti ] + * Update translations and bump version + + -- jenkins Tue, 23 Aug 2022 00:09:46 +0200 + +nymea-app (1.3.14) bionic; urgency=medium + + [ Michael Zanetti ] + * Some fixes in the Energy View if there is only a producer + + -- jenkins Fri, 12 Aug 2022 00:18:40 +0200 + +nymea-app (1.3.13) bionic; urgency=medium + + [ Michael Zanetti ] + * Show an appropriate message if Z-Wave is not available on the system + + -- jenkins Wed, 10 Aug 2022 10:39:41 +0200 + +nymea-app (1.3.12) bionic; urgency=medium + + [ Michael Zanetti ] + * Some more fixes for Z-Wave + + -- jenkins Mon, 08 Aug 2022 23:53:35 +0200 + +nymea-app (1.3.11) bionic; urgency=medium + + [ Michael Zanetti ] + * Show more details about the zwave controller + + -- jenkins Thu, 04 Aug 2022 22:27:11 +0200 + +nymea-app (1.3.10) bionic; urgency=medium + + [ Michael Zanetti ] + * Some fixes and improvements for Z-Wave + + -- jenkins Tue, 02 Aug 2022 22:22:33 +0200 + +nymea-app (1.3.9) bionic; urgency=medium + + [ Michael Zanetti ] + * Add Z-Wave support + + -- jenkins Fri, 29 Jul 2022 19:59:47 +0200 + +nymea-app (1.3.8) bionic; urgency=medium + + [ Michael Zanetti ] + * Only load plugin configs on demand + + -- jenkins Thu, 28 Jul 2022 17:51:50 +0200 + +nymea-app (1.3.7) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix nymea:// uri handling on ubuntu touch + * Fix hiding the EnergyView configuration button if there's nothing to + configure + * Fix background of consumption balance pie chart if all values are 0 + + -- jenkins Tue, 26 Jul 2022 15:04:13 +0200 + +nymea-app (1.3.6) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix irrigation auto-off rule + + -- jenkins Mon, 18 Jul 2022 11:47:19 +0200 + +nymea-app (1.3.5) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix unit in consumers pie chart (kWh -> kW) + + -- jenkins Mon, 11 Jul 2022 14:15:04 +0200 + +nymea-app (1.3.4) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for deep linking through push notification data + * Add encryption declaration for macOS to Info.plist + + -- jenkins Fri, 08 Jul 2022 15:17:57 +0200 + +nymea-app (1.3.3) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix the tunnel proxy configuration sometimes getting lost on sync + + -- jenkins Sun, 03 Jul 2022 20:31:56 +0200 + +nymea-app (1.3.2) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix tunnel proxy configurations being messed up on reconnects during + runtime + * Fix android navigation panel color + + -- jenkins Sun, 03 Jul 2022 15:13:49 +0200 + +nymea-app (1.3.1) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix a potential crash when destroying ProxyModels + + -- jenkins Sat, 02 Jul 2022 13:16:42 +0200 + +nymea-app (1.3.0) bionic; urgency=medium + + [ Michael Zanetti ] + * Bump version to 1.3.0 + + -- jenkins Fri, 01 Jul 2022 20:50:11 +0200 + +nymea-app (1.2.10) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix the new background handling on older Qt versions + + -- jenkins Fri, 01 Jul 2022 19:34:13 +0200 + +nymea-app (1.2.9) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve energy tooltips a little more + + -- jenkins Fri, 01 Jul 2022 17:56:48 +0200 + +nymea-app (1.2.8) bionic; urgency=medium + + [ Michael Zanetti ] + * Revert early initialisation of the web engine + + -- jenkins Fri, 01 Jul 2022 08:34:32 +0200 + +nymea-app (1.2.5) bionic; urgency=medium + + [ Michael Zanetti ] + * Fixes and optimizations + + -- jenkins Tue, 28 Jun 2022 15:07:51 +0200 + +nymea-app (1.2.4) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix some back buttons in the wifi setup wizard + + -- jenkins Thu, 23 Jun 2022 11:33:22 +0200 + +nymea-app (1.2.3) bionic; urgency=medium + + [ Michael Zanetti ] + * Some visual tweaks in the energy view + + -- jenkins Wed, 22 Jun 2022 18:10:13 +0200 + +nymea-app (1.2.2) bionic; urgency=medium + + [ Michael Zanetti ] + * Rework bottom panel + + -- jenkins Wed, 22 Jun 2022 17:13:12 +0200 + +nymea-app (1.2.1) bionic; urgency=medium + + [ Michael Zanetti ] + * Replace white push button box image with black one + + -- jenkins Mon, 20 Jun 2022 16:18:43 +0200 + +nymea-app (1.2.0) bionic; urgency=medium + + [ Michael Zanetti ] + * Bump version + * Update translations + + -- jenkins Thu, 16 Jun 2022 23:11:10 +0200 + +nymea-app (1.1.6) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix power balance stats sometimes not being initialized properly + * Hide battery stats when there are no energy storages installed + * Fix for some light controls being invisible after entering details + view + + -- jenkins Tue, 14 Jun 2022 00:46:17 +0200 + +nymea-app (1.1.5) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix some typos + + -- jenkins Wed, 08 Jun 2022 13:14:58 +0200 + +nymea-app (1.1.4) bionic; urgency=medium + + [ Michael Zanetti ] + * Automatically turn lights on/off when brightness moves from/to 0 + + -- jenkins Fri, 03 Jun 2022 16:02:01 +0200 + +nymea-app (1.1.3) bionic; urgency=medium + + [ Michael Zanetti ] + * Allow launching custom pages from main menu entries + + -- jenkins Fri, 03 Jun 2022 10:35:46 +0200 + +nymea-app (1.1.2) bionic; urgency=medium + + [ Michael Zanetti ] + * Hide user settings on system with push button auth + + -- jenkins Wed, 01 Jun 2022 23:03:48 +0200 + +nymea-app (1.1.1) bionic; urgency=medium + + [ Michael Zanetti ] + * Allow executing code in main menu links configuration + + -- jenkins Wed, 01 Jun 2022 20:05:45 +0200 + +nymea-app (1.1.0) bionic; urgency=medium + + [ Michael Zanetti ] + * Bump version to 1.1.0 + + -- jenkins Thu, 12 May 2022 12:36:38 +0200 + +nymea-app (1.0.461) bionic; urgency=medium + + [ Michael Zanetti ] + * Update translations + + -- jenkins Wed, 11 May 2022 14:04:35 +0200 + +nymea-app (1.0.459) bionic; urgency=medium + + [ Michael Zanetti ] + * Add android x86 + * Update tunnel proxy url in connection wizard + + -- jenkins Tue, 10 May 2022 14:42:58 +0200 + +nymea-app (1.0.458) bionic; urgency=medium + + [ Michael Zanetti ] + * More radius + * Improve zigbee settings when a node has multiple things + + -- jenkins Sun, 08 May 2022 22:12:00 +0200 + +nymea-app (1.0.457) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve sensor views + + -- jenkins Sun, 08 May 2022 02:54:02 +0200 + +nymea-app (1.0.456) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix color scheme to only use the new palette colors + + -- jenkins Fri, 06 May 2022 19:46:09 +0200 + +nymea-app (1.0.455) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve energy charts when there is a hidden producer + * Fix fingerprint reader setup page + * Confirm the login form on enter + + -- jenkins Fri, 06 May 2022 14:58:38 +0200 + +nymea-app (1.0.454) bionic; urgency=medium + + [ Michael Zanetti ] + * Improvements in the energy view + * Fix count property in zigbeedevicesproxy + * Add debug category for bluetooth discovery + + -- jenkins Mon, 25 Apr 2022 09:40:22 +0200 + +nymea-app (1.0.453) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix syncing aws devices when they don't have a uuid as id + + -- jenkins Fri, 22 Apr 2022 19:58:38 +0200 + +nymea-app (1.0.452) bionic; urgency=medium + + [ Michael Zanetti ] + * Add autocompletion for minimumValue and maximumValue in script + editor + * Add icon for car interface + * Don't show wrong time zone in settings page + * Update click package for latest frameworks/clickable + + -- jenkins Fri, 22 Apr 2022 10:59:09 +0200 + +nymea-app (1.0.451) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix server time display when client and server timezone don't line + up + * Fix zigbee settings loading spinner + * Add mellow style + + -- jenkins Wed, 20 Apr 2022 15:40:03 +0200 + +nymea-app (1.0.449) bionic; urgency=medium + + [ Michael Zanetti ] + * Make androidssl submodule shallow + * Show consumption history also if there's only a root meter + + -- jenkins Fri, 08 Apr 2022 11:09:12 +0200 + +nymea-app (1.0.448) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix permission handling after push button auth + + -- Jenkins Mon, 28 Mar 2022 13:59:52 +0200 + +nymea-app (1.0.447) bionic; urgency=medium + + [ Michael Zanetti ] + * Revert "Hide producer bars in power balance stats when there are no + p… + + -- Jenkins Sat, 26 Mar 2022 13:38:11 +0100 + +nymea-app (1.0.446) bionic; urgency=medium + + [ Michael Zanetti ] + * Hide producer bars in power balance stats when there are no + producers + * Small ventilation interfaces fixes + + -- Jenkins Fri, 25 Mar 2022 21:00:09 +0100 + +nymea-app (1.0.445) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve some debug prints in the things discovery + * Add more colors to the energy charts + + -- Jenkins Wed, 23 Mar 2022 19:48:23 +0100 + +nymea-app (1.0.444) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix energy view when there is no root meter + + -- Jenkins Tue, 22 Mar 2022 01:14:14 +0100 + +nymea-app (1.0.443) bionic; urgency=medium + + [ Michael Zanetti ] + * Add a highlight to energy bar charts + + -- Jenkins Mon, 21 Mar 2022 22:31:50 +0100 + +nymea-app (1.0.442) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix consumers history double loading glitch + * Fix tooltips for powerbalance history graphs + + -- Jenkins Mon, 21 Mar 2022 15:04:55 +0100 + +nymea-app (1.0.441) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix thing state logs + + -- Jenkins Sat, 19 Mar 2022 15:04:05 +0100 + +nymea-app (1.0.440) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix syncing of remote connection settings directly on activation + * More translation fixes + + -- Jenkins Fri, 18 Mar 2022 20:06:10 +0100 + +nymea-app (1.0.439) bionic; urgency=medium + + [ Michael Zanetti ] + * Rework remote connection settings + * Set default debug level to warning + + -- Jenkins Thu, 17 Mar 2022 10:17:40 +0100 + +nymea-app (1.0.438) bionic; urgency=medium + + [ Michael Zanetti ] + * Update translations + + -- Jenkins Wed, 16 Mar 2022 23:49:23 +0100 + +nymea-app (1.0.437) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix OSK size not always being correct with GBoard + * Fix opening package details from main update page + + -- Jenkins Wed, 16 Mar 2022 14:48:18 +0100 + +nymea-app (1.0.436) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix debug category for cloud transport + * Fix calculation of samples for months and years + + -- Jenkins Tue, 15 Mar 2022 13:53:02 +0100 + +nymea-app (1.0.435) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for discoveryType + + -- Jenkins Tue, 01 Mar 2022 19:28:54 +0100 + +nymea-app (1.0.434) bionic; urgency=medium + + [ Michael Zanetti ] + * Make it work with Qt 5.9 again + * Fix initializing event descriptor params in rules wizard + * Fix discovery wizard if search results return instantly + * Update ZigbeeNodesProxy filter when a device changes reachable state + + -- Jenkins Mon, 21 Feb 2022 00:56:06 +0100 + +nymea-app (1.0.433) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix connecting via preferred connection + + -- Jenkins Sun, 20 Feb 2022 16:15:53 +0100 + +nymea-app (1.0.432) bionic; urgency=medium + + [ Simon Stürz ] + * Handle EnterPin setup method + + [ Michael Zanetti ] + * Fix a crash in the charts when adding/removing things + * Fix a potential crash in Energy logs when disconnecting older setups + + -- Jenkins Fri, 18 Feb 2022 12:13:58 +0100 + +nymea-app (1.0.431) bionic; urgency=medium + + [ Michael Zanetti ] + * Clean up preferred connection if it vanishes + * Add support for the virtual button/switch thing classes + + -- Jenkins Wed, 16 Feb 2022 14:40:47 +0100 + +nymea-app (1.0.430) bionic; urgency=medium + + [ Michael Zanetti ] + * Update rule editor to not use generated events for states any more + + -- Jenkins Fri, 11 Feb 2022 00:57:54 +0100 + +nymea-app (1.0.429) bionic; urgency=medium + + [ Michael Zanetti ] + * Verbose macOS bundle signing + * Fixes in the energy view + + -- Jenkins Thu, 10 Feb 2022 14:06:14 +0100 + +nymea-app (1.0.428) bionic; urgency=medium + + [ Michael Zanetti ] + * Allow overriding the macOS signing ID + * Fix re-pair thing call + + -- Jenkins Thu, 10 Feb 2022 10:21:30 +0100 + +nymea-app (1.0.427) bionic; urgency=medium + + [ Michael Zanetti ] + * Disable charts animations on Samsung S8 + + -- Jenkins Sun, 06 Feb 2022 13:08:10 +0100 + +nymea-app (1.0.426) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for the TI ZigBee backend + * Fix crash when syncing remote connection configs via a remote + connection + + -- Jenkins Sun, 06 Feb 2022 12:04:50 +0100 + +nymea-app (1.0.425) bionic; urgency=medium + + [ Michael Zanetti ] + * Update mac os certificate name to new Apple default + * Fix modbus baudrate selection + * Fix year in imprint + * Clip the list in the magic page + * Fix wrench icon in energy view missing if all consumers are disabled + + -- Jenkins Sun, 30 Jan 2022 02:03:51 +0100 + +nymea-app (1.0.423) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix import for older Qt versions + + [ Simon Stürz ] + * Add tunnel proxy remote connection + + -- Jenkins Sat, 22 Jan 2022 12:15:49 +0100 + +nymea-app (1.0.422) bionic; urgency=medium + + [ Michael Zanetti ] + * More work on multi-user support + + -- Jenkins Thu, 20 Jan 2022 17:53:56 +0100 + +nymea-app (1.0.421) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix version.txt parsing in android builds with QtCreator >= 6 + + -- Jenkins Thu, 20 Jan 2022 12:07:24 +0100 + +nymea-app (1.0.420) bionic; urgency=medium + + [ Michael Zanetti ] + * Make default main view and menu links configurable + * Fix permissions on systems that don't require authentication + * Fix VCS url in debian/control + + -- Jenkins Wed, 12 Jan 2022 14:33:53 +0100 + +nymea-app (1.0.419) bionic; urgency=medium + + [ Benjamin Zeller ] + * Add initial packaging for openSUSE + + [ Michael Zanetti ] + * Fixes and improvements in the energy charts + + -- Jenkins Wed, 05 Jan 2022 01:52:50 +0100 + +nymea-app (1.0.418) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for user permissions + + -- Jenkins Mon, 20 Dec 2021 01:11:44 +0100 + +nymea-app (1.0.417) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix the crash from previous commit for real + + -- Jenkins Sun, 19 Dec 2021 00:01:00 +0100 + +nymea-app (1.0.416) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix a crash that may happen during initial loading + + -- Jenkins Sat, 18 Dec 2021 14:10:19 +0100 + +nymea-app (1.0.415) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix shownThingClassIds filter for older Qt versions + * Improve reconnecting logic even more + + -- Jenkins Fri, 17 Dec 2021 16:00:25 +0100 + +nymea-app (1.0.414) bionic; urgency=medium + + [ Michael Zanetti ] + * Don't wait for all transport candidates to fail before retrying + + -- Jenkins Thu, 16 Dec 2021 15:23:58 +0100 + +nymea-app (1.0.413) bionic; urgency=medium + + [ Michael Zanetti ] + * Another little fix in finding the closest to timestamp in a history + log + + -- Jenkins Thu, 16 Dec 2021 12:10:07 +0100 + +nymea-app (1.0.412) bionic; urgency=medium + + [ Michael Zanetti ] + * Drop blurred label + * Improve tooltip dragging in energy charts + + -- Jenkins Thu, 16 Dec 2021 01:33:55 +0100 + +nymea-app (1.0.411) bionic; urgency=medium + + [ Michael Zanetti ] + * Optimize loading of things + + -- Jenkins Thu, 16 Dec 2021 00:26:01 +0100 + +nymea-app (1.0.410) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix findClosest() in logsmodel + * Some more fixes in the bluetooth discovery + + -- Jenkins Thu, 16 Dec 2021 00:02:32 +0100 + +nymea-app (1.0.409) bionic; urgency=medium + + [ Michael Zanetti ] + * Add configuration option to disable magic + + -- Jenkins Wed, 15 Dec 2021 13:30:27 +0100 + +nymea-app (1.0.408) bionic; urgency=medium + + [ Michael Zanetti ] + * Blur chart tooltips + * Fix header blur + + -- Jenkins Wed, 15 Dec 2021 00:49:49 +0100 + +nymea-app (1.0.407) bionic; urgency=medium + + [ Michael Zanetti ] + * Prevent mouse event stealing while inspecting chart tooltips + + -- Jenkins Tue, 14 Dec 2021 22:36:06 +0100 + +nymea-app (1.0.406) bionic; urgency=medium + + [ Michael Zanetti ] + * Hide settings while disconnected + * Some minor tunings in the EnergyView + + -- Jenkins Tue, 14 Dec 2021 16:11:35 +0100 + +nymea-app (1.0.405) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix a typo in german translation + + -- Jenkins Tue, 14 Dec 2021 15:17:05 +0100 + +nymea-app (1.0.404) bionic; urgency=medium + + [ Michael Zanetti ] + * Allow disabling plugin settings by configuration + + -- Jenkins Tue, 14 Dec 2021 12:40:48 +0100 + +nymea-app (1.0.403) bionic; urgency=medium + + [ Michael Zanetti ] + * Settings entries configuration + + -- Jenkins Mon, 13 Dec 2021 17:59:47 +0100 + +nymea-app (1.0.402) bionic; urgency=medium + + [ Michael Zanetti ] + * Update translations and translate new strings to german + + -- Jenkins Mon, 13 Dec 2021 17:36:04 +0100 + +nymea-app (1.0.401) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix the check whether the energy plugin is available or not + + -- Jenkins Mon, 13 Dec 2021 14:48:28 +0100 + +nymea-app (1.0.400) bionic; urgency=medium + + [ Michael Zanetti ] + * Use dynamic min/max values for thermostat view + + -- Jenkins Mon, 13 Dec 2021 01:27:59 +0100 + +nymea-app (1.0.399) bionic; urgency=medium + + [ Michael Zanetti ] + * Update energy views to finalized API + + -- Jenkins Mon, 13 Dec 2021 00:43:29 +0100 + +nymea-app (1.0.397) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix bluetoothEnabled state on iOS + + -- Jenkins Wed, 08 Dec 2021 10:42:01 +0100 + +nymea-app (1.0.396) bionic; urgency=medium + + [ Michael Zanetti ] + * Improvements in the energy view + + -- Jenkins Mon, 06 Dec 2021 01:02:06 +0100 + +nymea-app (1.0.395) bionic; urgency=medium + + [ Michael Zanetti ] + * Fixes in NymeaConnection + + -- Jenkins Wed, 01 Dec 2021 00:41:49 +0100 + +nymea-app (1.0.394) bionic; urgency=medium + + [ Michael Zanetti ] + * Immediately delete a disconnected transport + + -- Jenkins Tue, 30 Nov 2021 12:47:33 +0100 + +nymea-app (1.0.393) bionic; urgency=medium + + [ Michael Zanetti ] + * Add timestamps to app logs + + -- Jenkins Tue, 30 Nov 2021 10:39:57 +0100 + +nymea-app (1.0.392) bionic; urgency=medium + + [ Michael Zanetti ] + * Some fixes in the connection setup wizard + + -- Jenkins Mon, 29 Nov 2021 22:59:22 +0100 + +nymea-app (1.0.391) bionic; urgency=medium + + [ Michael Zanetti ] + * Add energymeters to consumers + * Add missing fl oz unit + + -- Jenkins Mon, 29 Nov 2021 22:03:31 +0100 + +nymea-app (1.0.390) bionic; urgency=medium + + [ Michael Zanetti ] + * Tune powerbalance stats + + -- Jenkins Mon, 29 Nov 2021 14:34:10 +0100 + +nymea-app (1.0.389) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix LogsModel::findClosest() returning entries before logging + started + + -- Jenkins Thu, 25 Nov 2021 14:11:00 +0100 + +nymea-app (1.0.388) bionic; urgency=medium + + [ Michael Zanetti ] + * Reenable energy views + + -- Jenkins Thu, 25 Nov 2021 10:48:33 +0100 + +nymea-app (1.0.387) bionic; urgency=medium + + [ Michael Zanetti ] + * Adjust energy view layouts + + -- Jenkins Thu, 25 Nov 2021 01:10:51 +0100 + +nymea-app (1.0.386) bionic; urgency=medium + + [ Michael Zanetti ] + * Rework energy view + + -- Jenkins Wed, 24 Nov 2021 19:59:40 +0100 + +nymea-app (1.0.385) bionic; urgency=medium + + [ Michael Zanetti ] + * Implement energy logger api + * Fix push notifications ids with branding + + -- Jenkins Fri, 19 Nov 2021 00:04:57 +0100 + +nymea-app (1.0.384) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for the providedInterfaces thing class property + + -- Jenkins Fri, 12 Nov 2021 12:14:48 +0100 + +nymea-app (1.0.381) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix german translation for the energy view placeholder + + -- Jenkins Fri, 12 Nov 2021 09:30:35 +0100 + +nymea-app (1.0.380) bionic; urgency=medium + + [ Michael Zanetti ] + * Add energy manager class + + -- Jenkins Tue, 09 Nov 2021 14:06:02 +0100 + +nymea-app (1.0.379) bionic; urgency=medium + + [ Michael Zanetti ] + * Add a blue color to stylebase + * Fix uint handling in event descriptor delegate + + -- Jenkins Wed, 03 Nov 2021 13:58:33 +0100 + +nymea-app (1.0.378) bionic; urgency=medium + + [ Michael Zanetti ] + * Don't depend on qt5-default any more + * Allow renaming Zigbee devices from the zigbee network config page + * Fix a crash when removing smart meters + + -- Jenkins Fri, 22 Oct 2021 20:12:52 +0200 + +nymea-app (1.0.377) bionic; urgency=medium + + [ Michael Zanetti ] + * Fixes in zigbee settings + + -- Jenkins Fri, 22 Oct 2021 09:09:24 +0200 + +nymea-app (1.0.376) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for selecting the channel on zigbee network creation + + -- Jenkins Thu, 21 Oct 2021 23:17:15 +0200 + +nymea-app (1.0.375) bionic; urgency=medium + + [ Michael Zanetti ] + * Add block size param to logs model + + -- Jenkins Thu, 21 Oct 2021 13:25:05 +0200 + +nymea-app (1.0.374) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix visuals for stateful garage doors + + -- Jenkins Tue, 19 Oct 2021 23:15:46 +0200 + +nymea-app (1.0.373) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix double value input in paramdelegates + + -- Jenkins Mon, 18 Oct 2021 14:35:04 +0200 + +nymea-app (1.0.372) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for the water level interface + + -- Jenkins Wed, 13 Oct 2021 00:03:31 +0200 + +nymea-app (1.0.371) bionic; urgency=medium + + [ Michael Zanetti ] + * More smaller fixes in energy views + + -- Jenkins Fri, 01 Oct 2021 17:50:35 +0200 + +nymea-app (1.0.370) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix layout issues in smart meter views + + -- Jenkins Fri, 01 Oct 2021 12:54:49 +0200 + +nymea-app (1.0.369) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix layout issues in smart meter views + + -- Jenkins Fri, 01 Oct 2021 11:59:05 +0200 + +nymea-app (1.0.368) bionic; urgency=medium + + [ Michael Zanetti ] + * Align font sizes across energy views + + -- Jenkins Fri, 01 Oct 2021 10:42:56 +0200 + +nymea-app (1.0.367) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve ev charger view and minor fixes in similar views + + -- Jenkins Fri, 01 Oct 2021 10:07:35 +0200 + +nymea-app (1.0.366) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for dynamic min/max state values + * Update UPnP discovery when the device interfaces change + + -- Jenkins Thu, 30 Sep 2021 12:01:10 +0200 + +nymea-app (1.0.365) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix reconfiguration of discovered things + + -- Jenkins Tue, 28 Sep 2021 13:56:27 +0200 + +nymea-app (1.0.364) bionic; urgency=medium + + [ Michael Zanetti ] + * Enable multicast entitlement on iOS + + -- Jenkins Mon, 27 Sep 2021 23:45:05 +0200 + +nymea-app (1.0.363) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve energy pages + * Fixes in UPnP discovery on iOS + + -- Jenkins Fri, 24 Sep 2021 23:04:41 +0200 + +nymea-app (1.0.362) bionic; urgency=medium + + [ Michael Zanetti ] + * Modernize and align controllable things pages + + -- Jenkins Mon, 20 Sep 2021 17:02:10 +0200 + +nymea-app (1.0.361) bionic; urgency=medium + + [ Michael Zanetti ] + * Bump QtZeroConf version + * Hide inactive instances more agressively + + -- Jenkins Sun, 19 Sep 2021 22:20:40 +0200 + +nymea-app (1.0.360) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix blurry logo with low res screens + + -- Jenkins Fri, 17 Sep 2021 18:24:07 +0200 + +nymea-app (1.0.359) bionic; urgency=medium + + [ Michael Zanetti ] + * Allow inverting the XYSeriesAdapter values + + -- Jenkins Fri, 17 Sep 2021 14:40:23 +0200 + +nymea-app (1.0.358) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix tagwatcher not filtering correctly in all circumstances + + -- Jenkins Wed, 15 Sep 2021 14:59:12 +0200 + +nymea-app (1.0.357) bionic; urgency=medium + + [ Michael Zanetti ] + * Clip notifications list + + -- Jenkins Wed, 15 Sep 2021 11:14:05 +0200 + +nymea-app (1.0.356) bionic; urgency=medium + + [ Michael Zanetti ] + * Bump QtZeroconf once more + + -- Jenkins Tue, 14 Sep 2021 11:14:49 +0200 + +nymea-app (1.0.355) bionic; urgency=medium + + [ Michael Zanetti ] + * Update to latest fixes + + -- Jenkins Tue, 14 Sep 2021 00:31:35 +0200 + +nymea-app (1.0.354) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix saving manual connections in config + * Update QtZeroConf commit + + -- Jenkins Mon, 13 Sep 2021 19:39:19 +0200 + +nymea-app (1.0.353) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix iOS top panel font color with phone dark mode and light style + + -- Jenkins Mon, 13 Sep 2021 14:06:02 +0200 + +nymea-app (1.0.352) bionic; urgency=medium + + [ Michael Zanetti ] + * Bigger blocksize in logs + * Reduce font size in graphs + + -- Jenkins Wed, 08 Sep 2021 15:18:37 +0200 + +nymea-app (1.0.351) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix static value selection in state descriptor editor + + -- Jenkins Mon, 30 Aug 2021 23:31:51 +0200 + +nymea-app (1.0.350) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix multiple connections setup when autoconnect option is given + + -- Jenkins Mon, 30 Aug 2021 22:30:39 +0200 + +nymea-app (1.0.349) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix text color in new thing filter panel + * Fix app name in controloverlay + + -- Jenkins Mon, 30 Aug 2021 21:31:07 +0200 + +nymea-app (1.0.348) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix updating of bt discovery results + + -- Jenkins Mon, 30 Aug 2021 15:54:44 +0200 + +nymea-app (1.0.347) bionic; urgency=medium + + [ Michael Zanetti ] + * Drop header color settings from style + + -- Jenkins Mon, 30 Aug 2021 11:53:18 +0200 + +nymea-app (1.0.346) bionic; urgency=medium + + [ Michael Zanetti ] + * Modernize the header visuals + + -- Jenkins Sun, 29 Aug 2021 21:06:30 +0200 + +nymea-app (1.0.345) bionic; urgency=medium + + [ Michael Zanetti ] + * Add constants for gray to style base + * Add 15 mins sample rate to xyseriesadapter + + -- Jenkins Wed, 25 Aug 2021 22:52:30 +0200 + +nymea-app (1.0.344) bionic; urgency=medium + + [ Michael Zanetti ] + * Add api to handle discovery errors better + + -- Jenkins Tue, 24 Aug 2021 16:38:24 +0200 + +nymea-app (1.0.343) bionic; urgency=medium + + [ Michael Zanetti ] + * Energy view fixes + + -- Jenkins Tue, 24 Aug 2021 14:46:54 +0200 + +nymea-app (1.0.342) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for gas and CO sensors + + -- Jenkins Sat, 21 Aug 2021 00:58:38 +0200 + +nymea-app (1.0.341) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix Bluetooth Discovery on Android again + + -- Jenkins Fri, 20 Aug 2021 12:54:22 +0200 + +nymea-app (1.0.340) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix setup for push notifications + * Show the URL for the debug interface + + -- Jenkins Thu, 19 Aug 2021 12:56:09 +0200 + +nymea-app (1.0.339) bionic; urgency=medium + + [ Michael Zanetti ] + * Update UBPorts package to Qt 5.12 + * Improve setup wizard for things + * Add support for state based value comparison in rules + * Fix webview clipping on OSX + * Use Button controls on thing tiles too + + -- Jenkins Wed, 18 Aug 2021 15:12:22 +0200 + +nymea-app (1.0.338) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for translating overlays + + -- Jenkins Wed, 18 Aug 2021 12:22:30 +0200 + +nymea-app (1.0.337) bionic; urgency=medium + + [ Michael Zanetti ] + * Add a configuration option to hide links in menu + + -- Jenkins Fri, 13 Aug 2021 18:33:26 +0200 + +nymea-app (1.0.336) bionic; urgency=medium + + [ Michael Zanetti ] + * Move ConnectionInfoDialog to be a component + + -- Jenkins Thu, 12 Aug 2021 13:58:08 +0200 + +nymea-app (1.0.335) bionic; urgency=medium + + [ Michael Zanetti ] + * Bump Android API target level to 30 + * Fix current index in main menu after a setup is aborted + * Fix button margins in wizard pages + + -- Jenkins Wed, 11 Aug 2021 21:44:28 +0200 + +nymea-app (1.0.334) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix value display for event descriptors with multiple params + * Fix a possible crash in ThingClassesProxy + * Persist generated device serial on Ubuntu Phone + * Disable main view configuration with branding + + -- Jenkins Tue, 10 Aug 2021 23:18:08 +0200 + +nymea-app (1.0.333) bionic; urgency=medium + + [ Michael Zanetti ] + * Compare BT devices based on uuid instead of mac address + + -- Jenkins Mon, 09 Aug 2021 13:45:34 +0200 + +nymea-app (1.0.332) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix duplicate BT discovery results on iOS + + -- Jenkins Mon, 09 Aug 2021 10:12:14 +0200 + +nymea-app (1.0.331) bionic; urgency=medium + + [ Michael Zanetti ] + * Add startup time to logs + * Adjust logging category for bluetooth discovery + + -- Jenkins Fri, 06 Aug 2021 19:45:24 +0200 + +nymea-app (1.0.330) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix translations generating in deb packages + * Fix smartmeter interfaces + + -- Jenkins Fri, 06 Aug 2021 14:50:28 +0200 + +nymea-app (1.0.329) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix generating translations in deb package build + + -- Jenkins Fri, 06 Aug 2021 13:39:36 +0200 + +nymea-app (1.0.328) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix parenting of ThingDescriptors + + -- Jenkins Thu, 05 Aug 2021 13:36:48 +0200 + +nymea-app (1.0.327) bionic; urgency=medium + + [ Michael Zanetti ] + * Update to latest bt discovery code + * Update translations + * Show interfaces in thing classs details + + -- Jenkins Wed, 04 Aug 2021 14:28:38 +0200 + +nymea-app (1.0.326) bionic; urgency=medium + + [ Michael Zanetti ] + * Add some more sensor support to inlinecontrols + + -- Jenkins Tue, 13 Jul 2021 11:33:33 +0200 + +nymea-app (1.0.325) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix an issue when editing rule action params + * Added support for O2, ORP and PH sensors + + -- Jenkins Sun, 11 Jul 2021 22:13:41 +0200 + +nymea-app (1.0.324) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix the current index when removing a configured host + * Make the webview work in the snap package + + -- Jenkins Wed, 07 Jul 2021 19:03:47 +0200 + +nymea-app (1.0.323) bionic; urgency=medium + + [ Michael Zanetti ] + * Adjust main menu to fit better with new connection setup + + -- Jenkins Tue, 06 Jul 2021 12:34:32 +0200 + +nymea-app (1.0.322) bionic; urgency=medium + + [ Michael Zanetti ] + * Allow including cpp sources in the overlay + * Allow running discoveries by interface + + -- Jenkins Mon, 05 Jul 2021 16:50:22 +0200 + +nymea-app (1.0.321) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix an occational crash in logsmodel + + -- Jenkins Sun, 04 Jul 2021 23:57:31 +0200 + +nymea-app (1.0.320) bionic; urgency=medium + + [ Michael Zanetti ] + * Add proper category for account interface + + -- Jenkins Fri, 02 Jul 2021 21:38:32 +0200 + +nymea-app (1.0.319) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix some imports that would prevent it from working on Qt 5.9 + * Simplify json notification api + + -- Jenkins Thu, 01 Jul 2021 01:17:32 +0200 + +nymea-app (1.0.318) bionic; urgency=medium + + [ Michael Zanetti ] + * Some fixes in the wizard + + -- Jenkins Tue, 29 Jun 2021 10:40:00 +0200 + +nymea-app (1.0.317) bionic; urgency=medium + + [ Simon Stürz ] + * Zigbee node management and JSON RPC API implementation + + -- Jenkins Mon, 28 Jun 2021 22:54:23 +0200 + +nymea-app (1.0.316) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix the script console not working directly after deploying a new + script + * Fix subtext in generic log viewer entries + + -- Jenkins Fri, 18 Jun 2021 22:49:01 +0200 + +nymea-app (1.0.315) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix visual glitch while loading the dashboard + + -- Jenkins Wed, 16 Jun 2021 01:03:43 +0200 + +nymea-app (1.0.314) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix icon sizing in main menu + + -- Jenkins Tue, 15 Jun 2021 23:02:39 +0200 + +nymea-app (1.0.313) bionic; urgency=medium + + [ Michael Zanetti ] + * Allow overriding the connect wizard by the overlay + + -- Jenkins Fri, 11 Jun 2021 16:18:36 +0200 + +nymea-app (1.0.312) bionic; urgency=medium + + [ Michael Zanetti ] + * New connection setup wizard + + -- Jenkins Thu, 10 Jun 2021 16:08:28 +0200 + +nymea-app (1.0.311) bionic; urgency=medium + + [ Michael Zanetti ] + * Some fixes in the Dashboard + + [ Simon Stürz ] + * Add support for the Modbus RTU hardware resource + + -- Jenkins Mon, 07 Jun 2021 22:38:41 +0200 + +nymea-app (1.0.310) bionic; urgency=medium + + [ Michael Zanetti ] + * Align RuleManager api with other apis and add more signals + + -- Jenkins Mon, 07 Jun 2021 20:35:29 +0200 + +nymea-app (1.0.309) bionic; urgency=medium + + [ Michael Zanetti ] + * Add a Dashboard main view + + -- Jenkins Sun, 06 Jun 2021 23:27:36 +0200 + +nymea-app (1.0.308) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix height of thing/interface/time selection in rule creation + * Add overlay support to iOS build + + -- Jenkins Sat, 29 May 2021 17:13:33 +0200 + +nymea-app (1.0.307) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix an issue when disabling screen dimming + + -- Jenkins Thu, 20 May 2021 00:07:11 +0200 + +nymea-app (1.0.306) bionic; urgency=medium + + [ Michael Zanetti ] + * Don't delete discovery objects while not needed + * Fix ventilation control + * Rework button visuals + + -- Jenkins Wed, 19 May 2021 16:21:31 +0200 + +nymea-app (1.0.305) bionic; urgency=medium + + [ Michael Zanetti ] + * Use dynamic app name for remote proxy connection + + -- Jenkins Fri, 07 May 2021 00:24:11 +0200 + +nymea-app (1.0.304) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix a crash in the weather view + * Update translations + * Improve some debug prints in nymeaconfiguration + + -- Jenkins Tue, 27 Apr 2021 15:20:34 +0200 + +nymea-app (1.0.303) bionic; urgency=medium + + [ Michael Zanetti ] + * some fixes in the graph series adapter + + -- Jenkins Fri, 16 Apr 2021 17:49:52 +0200 + +nymea-app (1.0.302) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix an occationaly crash in logsmodel + * Add support cleaning robots + + -- Jenkins Mon, 12 Apr 2021 23:57:10 +0200 + +nymea-app (1.0.301) bionic; urgency=medium + + [ Michael Zanetti ] + * Add api to filter for thing class ids + + -- Jenkins Sat, 10 Apr 2021 15:16:56 +0200 + +nymea-app (1.0.300) bionic; urgency=medium + + [ Michael Zanetti ] + * Added a TagWatcher component + * Convert some old debug prints to new ones + + -- Jenkins Sat, 10 Apr 2021 00:29:31 +0200 + +nymea-app (1.0.299) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix windows package + + -- Jenkins Wed, 07 Apr 2021 20:41:24 +0200 + +nymea-app (1.0.298) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix log exporting + + -- Jenkins Tue, 06 Apr 2021 13:13:07 +0200 + +nymea-app (1.0.297) bionic; urgency=medium + + [ Michael Zanetti ] + * Only start the reconnect timer once + * Make the cloud discovery a bit easier to work with + * Rework overlay mechanism + + -- Jenkins Thu, 01 Apr 2021 23:58:20 +0200 + +nymea-app (1.0.296) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix bearer for manual connection + * Fix firebase path + + -- Jenkins Mon, 29 Mar 2021 13:01:47 +0200 + +nymea-app (1.0.295) bionic; urgency=medium + + [ Michael Zanetti ] + * Prioritze the used connections by taking last seen time into account + * Fix updating the tags proxy on dataChanged + + -- Jenkins Thu, 25 Mar 2021 19:57:33 +0100 + +nymea-app (1.0.294) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix event params in eventTriggered signal + + -- Jenkins Wed, 24 Mar 2021 20:15:41 +0100 + +nymea-app (1.0.293) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix awning control spacing + * Follow OS light/dark mode + * Cleanup warnings + + -- Jenkins Wed, 24 Mar 2021 17:54:00 +0100 + +nymea-app (1.0.292) bionic; urgency=medium + + [ Michael Zanetti ] + * Add signals for thing added and removed + + -- Jenkins Tue, 23 Mar 2021 15:47:42 +0100 + +nymea-app (1.0.291) bionic; urgency=medium + + [ Michael Zanetti ] + * Add a method to allow checking if a token exists for a particular + host + * Dont hide splash if autoconnecting + + -- Jenkins Mon, 22 Mar 2021 20:06:29 +0100 + +nymea-app (1.0.290) bionic; urgency=medium + + [ Michael Zanetti ] + * Require the "splash" kernel command line argument + + -- Jenkins Sun, 21 Mar 2021 23:31:15 +0100 + +nymea-app (1.0.289) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix splash screen + * Improve screen brightness control + + -- Jenkins Sun, 21 Mar 2021 19:52:14 +0100 + +nymea-app (1.0.288) bionic; urgency=medium + + [ Michael Zanetti ] + * Add splash support + + -- Jenkins Sun, 21 Mar 2021 16:25:13 +0100 + +nymea-app (1.0.287) bionic; urgency=medium + + [ Michael Zanetti ] + * Add ScriptProxyModel + * Add device serial api + * Fix refreshing the push token + + -- Jenkins Fri, 19 Mar 2021 14:39:37 +0100 + +nymea-app (1.0.286) bionic; urgency=medium + + [ Michael Zanetti ] + * Allow filtering for multiple thing class ids + * Fix AppLogController to activate changes immediately + * Fix state selection in rule page + + -- Jenkins Tue, 16 Mar 2021 23:08:24 +0100 + +nymea-app (1.0.285) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix thing discovery params + * Fix a crash that could happen when destroying LogsModel + + -- Jenkins Tue, 16 Mar 2021 19:07:59 +0100 + +nymea-app (1.0.284) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix discovery + + -- Jenkins Sun, 14 Mar 2021 15:35:19 +0100 + +nymea-app (1.0.283) bionic; urgency=medium + + [ Michael Zanetti ] + * Update battery interface + * Move AppLogController to libnymea-app + + -- Jenkins Sun, 14 Mar 2021 01:19:30 +0100 + +nymea-app (1.0.282) bionic; urgency=medium + + [ Michael Zanetti ] + * Remove some noisy debug prints + * Keep more logs + * Fix visual glitches in OAuth flow + + -- Jenkins Thu, 11 Mar 2021 23:24:58 +0100 + +nymea-app (1.0.281) bionic; urgency=medium + + [ Michael Zanetti ] + * Simplify ZigBee settings + + -- Jenkins Sun, 07 Mar 2021 22:47:12 +0100 + +nymea-app (1.0.280) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix snap version + * Cleanup legacy + * Update clickable file for newer clickable version + * Fix message when there are no wireless interfaces + + [ Michał Sawicz ] + * [snap] add daemon mode + * [snap] refresh and add GitHub workflow + + -- Jenkins Sun, 07 Mar 2021 12:29:10 +0100 + +nymea-app (1.0.279) bionic; urgency=medium + + [ Michael Zanetti ] + * Update translations + + -- Jenkins Wed, 03 Mar 2021 20:56:59 +0100 + +nymea-app (1.0.278) bionic; urgency=medium + + [ Michael Zanetti ] + * Declare iOS encryption in the Info.plist file + + -- Jenkins Tue, 02 Mar 2021 23:39:16 +0100 + +nymea-app (1.0.277) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix Thing tile for mediaplayers that also implement the power + interface + * Fix eventdescriptor params in edit rule page + * Fix default scene icons + * Fix wind speed display in weather view + * Fix changed signal when new hosts are discovered + + -- Jenkins Thu, 25 Feb 2021 23:51:00 +0100 + +nymea-app (1.0.276) bionic; urgency=medium + + [ Michael Zanetti ] + * Rename editDevice to editThing + * Inlude also the previous runs logs in the applogcontroller + * Fix a crash on engine destruction + * update evcharger interface + * Fix volume slider limits if a thing doesn't have volume from 0 to + 100 + + -- Jenkins Fri, 19 Feb 2021 00:40:15 +0100 + +nymea-app (1.0.275) bionic; urgency=medium + + [ Michael Zanetti ] + * Update devices to things in interfacesproxy + * Add x86_64 support for android build + + -- Jenkins Sat, 13 Feb 2021 14:29:40 +0100 + +nymea-app (1.0.274) bionic; urgency=medium + + [ Michael Zanetti ] + * Allow disabling individual discovery methods + * Tweak plugin settings pages + * Fix mouse area size of the progressbutton + * Fix group action executions + + -- Jenkins Fri, 12 Feb 2021 23:56:49 +0100 + +nymea-app (1.0.273) bionic; urgency=medium + + [ Michael Zanetti ] + * Some fixes for units (pressure mostly) + * Extract certificate data before disconnecting + + -- Jenkins Sat, 30 Jan 2021 23:22:02 +0100 + +nymea-app (1.0.272) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix encryption flag erraneously set for "ws" connections + * Revert "Update the Mac signing ID to the new default by apple" + + -- Jenkins Sat, 23 Jan 2021 20:30:21 +0100 + +nymea-app (1.0.271) bionic; urgency=medium + + [ Michael Zanetti ] + * Don't automatically pair the cloud every time we refresh something + from the cloud + + -- Jenkins Thu, 21 Jan 2021 13:24:29 +0100 + +nymea-app (1.0.270) bionic; urgency=medium + + [ Michael Zanetti ] + * Allow changing the connection given by the --connect flag + * Update the Mac signing ID to the new default by apple + * Fix cloud pairing not working automagically in all cases + * Rename Devices to Things in tags api + * Some fixes in the energy view + * Rename removeDevice to removeThing + + -- Jenkins Wed, 20 Jan 2021 22:07:55 +0100 + +nymea-app (1.0.269) bionic; urgency=medium + + [ Michael Zanetti ] + * Some more fixes in the BT discovery + + -- Jenkins Thu, 14 Jan 2021 14:59:44 +0100 + +nymea-app (1.0.268) bionic; urgency=medium + + [ Michael Zanetti ] + * Add sorting capability to generic sortfilter proxy model + * Retry the connection if the discovery finds more URLs for a host + afte… + * Rename DeviceDiscovery to ThingDiscovery + * Improve bt setup + * Create a pri for the lib + + -- Jenkins Thu, 14 Jan 2021 00:38:23 +0100 + +nymea-app (1.0.267) bionic; urgency=medium + + [ Michael Zanetti ] + * Allow resizing the console/error panel in the scripteditor + + -- Jenkins Sat, 09 Jan 2021 19:34:47 +0100 + +nymea-app (1.0.266) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix weather device list page + * Some improvements in the Script autocompletion + + -- Jenkins Sat, 09 Jan 2021 12:54:18 +0100 + +nymea-app (1.0.265) bionic; urgency=medium + + [ Michael Zanetti ] + * Fixes for push notifications + * Fix a warning in the gradlew script + + -- Jenkins Fri, 08 Jan 2021 22:15:54 +0100 + +nymea-app (1.0.264) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve smartmeter and sensor views + + -- Jenkins Wed, 06 Jan 2021 19:32:01 +0100 + +nymea-app (1.0.263) bionic; urgency=medium + + [ Michael Zanetti ] + * Clean up warnings in code + * Fix presence sensor in sensors list view + + -- Jenkins Tue, 05 Jan 2021 19:16:11 +0100 + +nymea-app (1.0.262) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix UPnP when multiple hosts reply and add more debug + * Fix the default port for manual connections + * Improve thermostat views + * Revert the hotfix for broken desktop helpers + + -- Jenkins Sat, 02 Jan 2021 13:30:21 +0100 + +nymea-app (1.0.261) bionic; urgency=medium + + [ Michael Zanetti ] + * Update QtZeroConf + * Fix brightness settings + + -- Jenkins Wed, 23 Dec 2020 21:12:20 +0100 + +nymea-app (1.0.260) bionic; urgency=medium + + [ Michael Zanetti ] + * Make the screen helper more generic + * Fix erraneously displayed powet switch in generic list page + * Allow changing the tile overlay icon color in the style + + -- Jenkins Sun, 20 Dec 2020 16:47:42 +0100 + +nymea-app (1.0.259) bionic; urgency=medium + + [ Michael Zanetti ] + * Add some more media templates + * Views cmdline options + * More cmdline style options + * Add a rule template for automatic night mode + + -- Jenkins Thu, 10 Dec 2020 00:21:21 +0100 + +nymea-app (1.0.258) bionic; urgency=medium + + [ Michael Zanetti ] + * Some fixes for regressions after the style changes + + -- Jenkins Mon, 07 Dec 2020 15:35:57 +0100 + +nymea-app (1.0.257) bionic; urgency=medium + + [ Michael Zanetti ] + * Rework the styling mechanism + + -- Jenkins Sun, 06 Dec 2020 18:27:54 +0100 + +nymea-app (1.0.256) bionic; urgency=medium + + [ Michael Zanetti ] + * More fixes for the media player + + -- Jenkins Sat, 05 Dec 2020 18:37:37 +0100 + +nymea-app (1.0.255) bionic; urgency=medium + + [ Michael Zanetti ] + * More fixes in things lists + + -- Jenkins Sat, 05 Dec 2020 02:15:25 +0100 + +nymea-app (1.0.254) bionic; urgency=medium + + [ Michael Zanetti ] + * Move main view configuration into menu + * Fixes and improvements for lights + + -- Jenkins Fri, 04 Dec 2020 13:48:23 +0100 + +nymea-app (1.0.253) bionic; urgency=medium + + [ Michael Zanetti ] + * Remove link in menu logo + * Make menu replace pages instead of pushing + * Fix garage views + + -- Jenkins Sun, 29 Nov 2020 18:58:07 +0100 + +nymea-app (1.0.252) bionic; urgency=medium + + [ Michael Zanetti ] + * Rework main menu + + -- Jenkins Sun, 29 Nov 2020 01:50:03 +0100 + +nymea-app (1.0.251) bionic; urgency=medium + + [ Michael Zanetti ] + * Rework media views for new interfaces + * Add support for autosaving in the script editor + * New tiles + + [ Simon Stürz ] + * Add support for zigbee network management + + -- Jenkins Sat, 28 Nov 2020 21:09:18 +0100 + +nymea-app (1.0.250) bionic; urgency=medium + + [ Michael Zanetti ] + * Sort groups alphabetically + * Fix invalid property access with Qt 5.15 in AppLogPage + * Fix adaptive icon on "round" launchers + * Use main views from branding if set + * Align param and state delegates better + + -- Jenkins Wed, 11 Nov 2020 16:48:38 +0100 + +nymea-app (1.0.249) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix snap package + * Allow builds with firebase to work on devices without play services + again + + -- Jenkins Thu, 29 Oct 2020 20:22:37 +0100 + +nymea-app (1.0.248) bionic; urgency=medium + + [ Michael Zanetti ] + * Allow building without firebase + * Clean up some list views + + -- Jenkins Sat, 24 Oct 2020 02:19:05 +0200 + +nymea-app (1.0.247) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for color the temperature picker in param delegates + * Allow overriding the complete android packaging structure for + branding + + -- Jenkins Mon, 19 Oct 2020 22:23:59 +0200 + +nymea-app (1.0.246) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix the Ubuntu phone build + + -- Jenkins Fri, 16 Oct 2020 13:49:16 +0200 + +nymea-app (1.0.245) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for writing NFC tags and launching stuff with them + + -- Jenkins Thu, 15 Oct 2020 20:01:19 +0200 + +nymea-app (1.0.243) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for interface based Actions/Event in ScriptEditor + + -- Jenkins Tue, 13 Oct 2020 18:51:28 +0200 + +nymea-app (1.0.242) bionic; urgency=medium + + [ Michael Zanetti ] + * Add Fastlane structure for F-Droid + * Fix Android Device Controls not always loading on initial setup + + -- Jenkins Tue, 29 Sep 2020 23:46:08 +0200 + +nymea-app (1.0.241) bionic; urgency=medium + + [ Michael Zanetti ] + * Make use of Google Play Services optional + + -- Jenkins Tue, 29 Sep 2020 19:59:21 +0200 + +nymea-app (1.0.239) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix app freeze when selecting a point in an empty graph + * Add barcode scanner grouping + * Fix entering uncategorized when there's only 1 thing + * Improve notifications view + * Allow overriding the header icon in styles + + -- Jenkins Mon, 28 Sep 2020 21:38:26 +0200 + +nymea-app (1.0.238) bionic; urgency=medium + + [ Michael Zanetti ] + * Reduce Android target API to 29 + + -- Jenkins Wed, 23 Sep 2020 13:49:54 +0200 + +nymea-app (1.0.237) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix entering thing pages + * Add new permission requests as required by iOS 14 + + -- Jenkins Tue, 22 Sep 2020 19:48:17 +0200 + +nymea-app (1.0.235) bionic; urgency=medium + + [ Michael Zanetti ] + * Move a java file to the correct .pro file + + -- Jenkins Tue, 22 Sep 2020 17:55:50 +0200 + +nymea-app (1.0.234) bionic; urgency=medium + + [ Michael Zanetti ] + * bump revision so we can try uploading it to google play again + + -- Jenkins Tue, 22 Sep 2020 12:22:52 +0200 + +nymea-app (1.0.231) bionic; urgency=medium + + [ Michael Zanetti ] + * Allow adding custom main views in the overlay + * Fix entering things pages when there's only one in the list + * Android device controls + + -- Jenkins Tue, 22 Sep 2020 10:34:09 +0200 + +nymea-app (1.0.230) bionic; urgency=medium + + [ Michael Zanetti ] + * Make use of the new caching mechanism in nymea + * Fix weather view crashing with Qt 5.15 + + -- Jenkins Tue, 15 Sep 2020 19:11:18 +0200 + +nymea-app (1.0.229) bionic; urgency=medium + + [ Michael Zanetti ] + * Make it work with Qt 5.15 + * Fix translation loading on android + * Fix a threading issue in AppLogController + + -- Jenkins Fri, 11 Sep 2020 13:06:39 +0200 + +nymea-app (1.0.228) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix graphs not filtering properly for type id + * Update ev charger icon + * Fix icons in ThingDelegate + + -- Jenkins Wed, 09 Sep 2020 01:05:52 +0200 + +nymea-app (1.0.227) bionic; urgency=medium + + [ Michael Zanetti ] + * Rearrange some connectivity icons + + -- Jenkins Sun, 06 Sep 2020 04:31:28 +0200 + +nymea-app (1.0.226) bionic; urgency=medium + + [ Michael Zanetti ] + * Make plugin issues more visible to the user + * Some fixes in zeroconf discovery + * Update the windows installer + + -- Jenkins Sat, 05 Sep 2020 22:41:11 +0200 + +nymea-app (1.0.225) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix the footer dropshadow + + -- Jenkins Sun, 30 Aug 2020 17:23:15 +0200 + +nymea-app (1.0.224) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix more views that broke on the LogsModel transition + * Autocomplete action params in script editor + * Fix inputtrigger view + * Fix warning because of bad arg usage + + -- Jenkins Sun, 30 Aug 2020 16:16:54 +0200 + +nymea-app (1.0.223) bionic; urgency=medium + + [ Michael Zanetti ] + * Make Pane corners slightly rounded in energize style + + -- Jenkins Sat, 29 Aug 2020 20:26:37 +0200 + +nymea-app (1.0.222) bionic; urgency=medium + + [ Michael Zanetti ] + * More fixes and translations + + -- Jenkins Fri, 28 Aug 2020 17:21:05 +0200 + +nymea-app (1.0.221) bionic; urgency=medium + + [ Michael Zanetti ] + * Fixes and translations + * Add engergize style + + -- Jenkins Thu, 27 Aug 2020 19:03:07 +0200 + +nymea-app (1.0.220) bionic; urgency=medium + + [ Michael Zanetti ] + * Make the main view more customizable + * Fix broken button box style in lime style + + -- Jenkins Thu, 27 Aug 2020 16:12:08 +0200 + +nymea-app (1.0.219) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve irrigation view, add support for time based rule templates + + -- Jenkins Sat, 15 Aug 2020 00:24:46 +0200 + +nymea-app (1.0.218) bionic; urgency=medium + + [ Michael Zanetti ] + * Fixes in garage door and barcode scanner related UIs + + -- Jenkins Thu, 06 Aug 2020 16:18:38 +0200 + +nymea-app (1.0.217) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for barcode scanners + + -- Jenkins Thu, 06 Aug 2020 01:16:51 +0200 + +nymea-app (1.0.216) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix creating interface based rules with event based parameters + + -- Jenkins Wed, 05 Aug 2020 14:19:44 +0200 + +nymea-app (1.0.215) bionic; urgency=medium + + [ Michael Zanetti ] + * Dynamically show/hide the mouse cursor, depending on the input type + + -- Jenkins Tue, 04 Aug 2020 11:35:13 +0200 + +nymea-app (1.0.214) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve garage door views + * Update help url for the script editor + + -- Jenkins Mon, 03 Aug 2020 15:24:17 +0200 + +nymea-app (1.0.213) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve color picker throttling + * User proper type for eventtypeId in events from things + + -- Jenkins Mon, 20 Jul 2020 19:21:52 +0200 + +nymea-app (1.0.212) bionic; urgency=medium + + [ Michael Zanetti ] + * Show browser error messages to the user when available + * Fix event inidication LED in things details page + * Rework closable views and add support for venetian blinds + + -- Jenkins Mon, 06 Jul 2020 14:21:26 +0200 + +nymea-app (1.0.211) bionic; urgency=medium + + [ Michael Zanetti ] + * Update translations + * Add a thing class viewer page to thing settings + + -- Jenkins Mon, 08 Jun 2020 17:57:03 +0200 + +nymea-app (1.0.210) bionic; urgency=medium + + [ Michael Zanetti ] + * Add ID to the thing config page + + -- Jenkins Mon, 08 Jun 2020 11:34:51 +0200 + +nymea-app (1.0.209) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix description for debian/ubuntu package + + -- Jenkins Wed, 27 May 2020 19:55:10 +0200 + +nymea-app (1.0.208) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for the ventilation interface + * Reduce some warnings from QML + * Improve thing pages with graphs + + -- Jenkins Wed, 27 May 2020 11:59:28 +0200 + +nymea-app (1.0.207) bionic; urgency=medium + + [ Michael Zanetti ] + * Support inverted IO connections + * Don't use ResetRole in dialog + * Improve attached properties in scripting code completion + * Fix the browsers context menu positioning + + -- Jenkins Sun, 10 May 2020 22:56:41 +0200 + +nymea-app (1.0.206) bionic; urgency=medium + + [ Michael Zanetti ] + * Small improvements in the edit rules page + + -- Jenkins Thu, 07 May 2020 17:51:04 +0200 + +nymea-app (1.0.205) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for restarting nymea in the settings + * Add support for allowed values in number type params + * Add support for AP mode in settings and display IP address configs + * Fix building with ZeroConf disabled + * Add support for the irrigation interface + * Add support for generic IO connections + + -- Jenkins Wed, 06 May 2020 00:16:29 +0200 + +nymea-app (1.0.204) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix pushbutton auth appearing to fail on a first set + * Improve network settings + + -- Jenkins Thu, 23 Apr 2020 18:05:26 +0200 + +nymea-app (1.0.203) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix Scripting code completion with just one entry + + -- Jenkins Tue, 21 Apr 2020 15:58:09 +0200 + +nymea-app (1.0.202) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve certificate pinning mechanism + + -- Jenkins Sun, 19 Apr 2020 15:24:07 +0200 + +nymea-app (1.0.201) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix popping the page stack when things are deleted + * Fix time zone handling on Android + * Don't allow editing read only params + + -- Jenkins Sat, 11 Apr 2020 12:41:51 +0200 + +nymea-app (1.0.200) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix filtering for uncategorized on main page tile + + -- Jenkins Sun, 05 Apr 2020 19:48:06 +0200 + +nymea-app (1.0.199) bionic; urgency=medium + + [ Michael Zanetti ] + * Update upstream android-ssl + * Fix the snap package after including desktop helpers + + -- Jenkins Sat, 04 Apr 2020 12:19:38 +0200 + +nymea-app (1.0.198) bionic; urgency=medium + + [ Michael Zanetti ] + * Update translations + + -- Jenkins Fri, 03 Apr 2020 23:26:52 +0200 + +nymea-app (1.0.197) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix setting iOS status bar color with new xcode apis + + -- Jenkins Fri, 03 Apr 2020 20:46:41 +0200 + +nymea-app (1.0.196) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix unit for pressure in weather view + * Fix providing param overrides for rediscovery + * Fix the check for preventing to remove auto things + * Fix ios appicon catalog + + -- Jenkins Fri, 03 Apr 2020 12:29:54 +0200 + +nymea-app (1.0.195) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix resource config for AAB package + + -- Jenkins Wed, 01 Apr 2020 23:31:00 +0200 + +nymea-app (1.0.194) bionic; urgency=medium + + [ Michael Zanetti ] + * Update android packaging to support Qt 5.14 + + -- Jenkins Wed, 01 Apr 2020 19:40:54 +0200 + +nymea-app (1.0.193) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix opening links from the snap package + + -- Jenkins Tue, 31 Mar 2020 13:22:24 +0200 + +nymea-app (1.0.192) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix units in dynamic graph view updates + + -- Jenkins Sun, 29 Mar 2020 20:23:42 +0200 + +nymea-app (1.0.191) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix interfaces handling + * Add Thing items and thingId support to script editor + + -- Jenkins Sun, 29 Mar 2020 01:09:32 +0100 + +nymea-app (1.0.190) bionic; urgency=medium + + [ Michael Zanetti ] + * Change group behavior a bit + + -- Jenkins Fri, 27 Mar 2020 01:05:37 +0100 + +nymea-app (1.0.189) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix font color on dark headers + * Allow removing childs which weren't autocreated + * Add Radio Paradise icon + + -- Jenkins Thu, 26 Mar 2020 19:35:52 +0100 + +nymea-app (1.0.188) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix log viewers string/uuid conversion + * Fix spaces and umlauts in code completion for deviceId + + -- Jenkins Tue, 17 Mar 2020 12:51:27 +0100 + +nymea-app (1.0.187) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix LogViewer and Weather view unit conversion + + -- Jenkins Thu, 05 Mar 2020 11:55:13 +0100 + +nymea-app (1.0.186) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix building with latest clickable + * Add a Placeholder in button views if there are no presses yet + * Add support for changing the password and manage tokens + * Make use of the new setupStatus property + + -- Jenkins Wed, 26 Feb 2020 19:43:36 +0100 + +nymea-app (1.0.185) bionic; urgency=medium + + [ Michael Zanetti ] + * Reduce minimum tile size to support 2 columns on most devices + * Fix an assertion when there are no tags + * Revert "Fix the app bundle name in the macOS installer." + + -- Jenkins Wed, 19 Feb 2020 22:58:22 +0100 + +nymea-app (1.0.184) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix crash on startup on some android phones + * Fix error code missing in error message + + -- Jenkins Fri, 07 Feb 2020 12:31:12 +0100 + +nymea-app (1.0.183) bionic; urgency=medium + + [ Michael Zanetti ] + * Update translations + * Open context menu on longpress in list items + * Hide the delete option on child devices + * Fix dropshadow of tabbed views reaching into other tabs + * Fix the app bundle name in the macOS installer. + * Copyright + + -- Jenkins Mon, 03 Feb 2020 23:37:08 +0100 + +nymea-app (1.0.182) bionic; urgency=medium + + [ Michael Zanetti ] + * Don't change viewmode "by accident" + * Fix grouping by base interface + + -- Jenkins Fri, 31 Jan 2020 01:01:12 +0100 + +nymea-app (1.0.181) bionic; urgency=medium + + [ Michael Zanetti ] + * Allow building different architectures with clickable + + -- Jenkins Thu, 23 Jan 2020 23:42:04 +0100 + +nymea-app (1.0.180) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix dependency to Qt.labs.calendar for click, snap and dpkg + + -- Jenkins Thu, 23 Jan 2020 16:20:54 +0100 + +nymea-app (1.0.179) bionic; urgency=medium + + [ Michael Zanetti ] + * Add info about Qt versions in about pages + + -- Jenkins Tue, 21 Jan 2020 23:35:49 +0100 + +nymea-app (1.0.178) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for imperial unit conversion + * Fix signing of the macOS app bundle + + -- Jenkins Tue, 21 Jan 2020 14:55:52 +0100 + +nymea-app (1.0.177) bionic; urgency=medium + + [ Michael Zanetti ] + * Enable building macOS AppStore compliant packages + + -- Jenkins Sat, 18 Jan 2020 02:09:37 +0100 + +nymea-app (1.0.176) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix SSL connections on windows + + -- Jenkins Sat, 18 Jan 2020 01:48:13 +0100 + +nymea-app (1.0.175) bionic; urgency=medium + + [ Michael Zanetti ] + * Reenable UPnP, regardless if ZeroConf is enabled already + + -- Jenkins Sat, 18 Jan 2020 01:31:39 +0100 + +nymea-app (1.0.174) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve ParamDelegate layout + * Allow filtering by vendor when adding new things + * Fix wording for heating and garagedoors + * Add a smartlock interface + * Add Bluetooth media browser icon + + -- Jenkins Thu, 16 Jan 2020 19:27:01 +0100 + +nymea-app (1.0.173) bionic; urgency=medium + + [ Michael Zanetti ] + * Implement new system time api + * Add a script editor for nymea scripts + + -- Jenkins Thu, 16 Jan 2020 11:43:35 +0100 + +nymea-app (1.0.172) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix AWS config casing + + -- Jenkins Tue, 14 Jan 2020 17:05:45 +0100 + +nymea-app (1.0.171) bionic; urgency=medium + + [ Michael Zanetti ] + * Make it build in sbuild + * Fix AWS testing environment at app startup + * Use The displayMessage in discovery results + + -- Jenkins Sun, 12 Jan 2020 22:12:28 +0100 + +nymea-app (1.0.170) bionic; urgency=medium + + [ Michael Zanetti ] + * Update the AWS device name when it changes in the cloud + * Use a more unique nonce for the remote connection + * Fix view mode breaking on iOS when opening Look and feel page + * Use accounts icon for account interface + + -- Jenkins Thu, 09 Jan 2020 13:50:50 +0100 + +nymea-app (1.0.169) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix the Add scene button + + -- Jenkins Tue, 17 Dec 2019 11:36:22 +0100 + +nymea-app (1.0.168) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve UBPorts support + + -- Jenkins Mon, 16 Dec 2019 16:58:14 +0100 + +nymea-app (1.0.167) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix setup of discovered devices with pairing + + -- Jenkins Sun, 15 Dec 2019 13:58:17 +0100 + +nymea-app (1.0.166) bionic; urgency=medium + + [ Michael Zanetti ] + * Don't use deprecated Events and Actions namespaces any more + + -- Jenkins Thu, 12 Dec 2019 14:29:45 +0100 + +nymea-app (1.0.165) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix new thing page after uuid changes + * Fix login field for things setup with a login + + -- Jenkins Tue, 10 Dec 2019 23:21:30 +0100 + +nymea-app (1.0.163) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix generating action type for rule creation + + -- Jenkins Sun, 08 Dec 2019 19:40:41 +0100 + +nymea-app (1.0.162) bionic; urgency=medium + + [ Michael Zanetti ] + * Hide group placeholder while loading + * Fix browserItemActionTypes + + -- Jenkins Mon, 02 Dec 2019 00:19:54 +0100 + +nymea-app (1.0.161) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix popup destruction + + -- Jenkins Sun, 01 Dec 2019 14:44:25 +0100 + +nymea-app (1.0.160) bionic; urgency=medium + + [ Michael Zanetti ] + * Work around QtVirtualKeyboard layering issues + + -- Jenkins Sun, 01 Dec 2019 12:56:31 +0100 + +nymea-app (1.0.159) bionic; urgency=medium + + [ Michael Zanetti ] + * Grouping + * Improve closable views a bit + * Complete support for reconfiguring devices + * Make use of new notifications subscription mechanism + + -- Jenkins Sat, 30 Nov 2019 18:22:10 +0100 + +nymea-app (1.0.158) bionic; urgency=medium + + [ Michael Zanetti ] + * Update password entry fields + * Fix the create a scene button + + -- Jenkins Mon, 25 Nov 2019 13:31:16 +0100 + +nymea-app (1.0.157) bionic; urgency=medium + + [ Michael Zanetti ] + * Don't use "-" for UnitNone + + -- Jenkins Tue, 19 Nov 2019 20:19:35 +0100 + +nymea-app (1.0.156) bionic; urgency=medium + + [ Michael Zanetti ] + * Don't compare QUUid with QStrings in an unsafe way + + -- Jenkins Mon, 18 Nov 2019 21:50:04 +0100 + +nymea-app (1.0.155) bionic; urgency=medium + + [ Michael Zanetti ] + * Try using the UserNotification framework + + -- Jenkins Thu, 14 Nov 2019 17:29:32 +0100 + +nymea-app (1.0.154) bionic; urgency=medium + + [ Michael Zanetti ] + * Revert iOS push notifications changes... + + -- Jenkins Thu, 14 Nov 2019 14:54:46 +0100 + +nymea-app (1.0.153) bionic; urgency=medium + + [ Michael Zanetti ] + * And another attempt to fix iOS push notifications... narf + + -- Jenkins Thu, 14 Nov 2019 12:06:34 +0100 + +nymea-app (1.0.152) bionic; urgency=medium + + [ Michael Zanetti ] + * Add a filter input field when adding new things + * Another attempt to fix push notifications + + -- Jenkins Thu, 14 Nov 2019 11:00:09 +0100 + +nymea-app (1.0.150) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix push notifications for iOS 13 + * Fix webserver public folder configuration + + -- Jenkins Thu, 14 Nov 2019 01:01:17 +0100 + +nymea-app (1.0.149) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix spacing of shutter controls + + -- Jenkins Mon, 28 Oct 2019 17:20:58 +0100 + +nymea-app (1.0.148) bionic; urgency=medium + + [ Michael Zanetti ] + * guh GmbH is now nymea GmbH + * More ruletemplates + * Fix initialization of networking page + * Fix device lists getting messed up when devices are reordered + * Update the app properly when the core system capabilities change + + -- Jenkins Mon, 28 Oct 2019 12:23:25 +0100 + +nymea-app (1.0.147) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve adding/removing repositories a bit + * Add more icons for media services + + [ Simon Stürz ] + * Fix fingerprint reader view + + -- Jenkins Fri, 11 Oct 2019 11:13:23 +0200 + +nymea-app (1.0.146) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix session startup scripts to work on buster + * Make the webview optional + + -- Jenkins Fri, 27 Sep 2019 19:22:09 +0200 + +nymea-app (1.0.145) bionic; urgency=medium + + [ Michael Zanetti ] + * Include NSBluetoothAlwaysUsageDescription in Info.plist + + -- Jenkins Fri, 27 Sep 2019 12:43:51 +0200 + +nymea-app (1.0.144) bionic; urgency=medium + + [ Michael Zanetti ] + * Allow thing settings to be opened directly from the things page + * Herz has been fixed to Hertz in the core + + -- Jenkins Fri, 27 Sep 2019 00:08:44 +0200 + +nymea-app (1.0.143) bionic; urgency=medium + + [ Michael Zanetti ] + * Also color the panel on android, fix iOS landscape mode + * Some fixes in the add device results page + + -- Jenkins Fri, 20 Sep 2019 01:21:28 +0200 + +nymea-app (1.0.142) bionic; urgency=medium + + [ Michael Zanetti ] + * Add a a fallback "en" translation + * Handle the iPhone notch better + * Strip QtWebengine's execstack in snap package + + -- Jenkins Thu, 19 Sep 2019 17:50:20 +0200 + +nymea-app (1.0.141) bionic; urgency=medium + + [ Michael Zanetti ] + * Call methods necessary to init QtWebView on some platforms + * Add missing icon for the loopback bearer type + * Fix sorting of vendors list in add thing dialog + * Fix ThingDelegate not updating connection status + * Improve rule creation + * Smoothen the volume slider + + -- Jenkins Sun, 01 Sep 2019 01:51:47 +0200 + +nymea-app (1.0.140) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for OAuth during thing setup + + -- Jenkins Wed, 28 Aug 2019 12:18:25 +0200 + +nymea-app (1.0.139) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix AWS credentials getting lost + + -- Jenkins Tue, 30 Jul 2019 10:44:46 +0200 + +nymea-app (1.0.138) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix some strings and translations + + -- Jenkins Thu, 25 Jul 2019 15:01:06 +0200 + +nymea-app (1.0.137) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for the keypad interface in media devices + + -- Jenkins Wed, 24 Jul 2019 09:56:57 +0200 + +nymea-app (1.0.136) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix item selection for rules in nested browser subpages + + -- Jenkins Thu, 18 Jul 2019 18:03:17 +0200 + +nymea-app (1.0.135) bionic; urgency=medium + + [ Michael Zanetti ] + * Add support for browsing things + * Improve back button handling + + -- Jenkins Thu, 18 Jul 2019 01:18:15 +0200 + +nymea-app (1.0.134) bionic; urgency=medium + + [ Michael Zanetti ] + * Add a lime theme + * Improve back button handling + + -- Jenkins Wed, 17 Jul 2019 12:23:30 +0200 + +nymea-app (1.0.133) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix an issue where the app might not reconnect to the core. + * Improve back button handling + + -- Jenkins Wed, 10 Jul 2019 19:52:27 +0200 + +nymea-app (1.0.132) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve back button handling + * Update to newer Android API + + -- Jenkins Sun, 07 Jul 2019 21:06:27 +0200 + +nymea-app (1.0.131) bionic; urgency=medium + + [ Michael Zanetti ] + * Update to latest upstream QtZeroConf + + -- Jenkins Fri, 05 Jul 2019 18:17:12 +0200 + +nymea-app (1.0.130) bionic; urgency=medium + + [ Michael Zanetti ] + * Rename some old components + * Support the upcoming powerswitch interface + * Add support for setting the screen brightness on Raspberry Pis + * Don't allow X to blank the screen + * Allow the "All lights off" button to also turn all lights on + + -- Jenkins Fri, 05 Jul 2019 01:25:36 +0200 + +nymea-app (1.0.129) bionic; urgency=medium + + [ Michael Zanetti ] + * Only include active bearers + + -- Jenkins Fri, 21 Jun 2019 00:38:56 +0200 + +nymea-app (1.0.128) bionic; urgency=medium + + [ Michael Zanetti ] + * Respawn the app in kiosk mode when it exits (e.g. on updates) + * Improve login page + + -- Jenkins Thu, 20 Jun 2019 22:47:49 +0200 + +nymea-app (1.0.127) bionic; urgency=medium + + [ Michael Zanetti ] + * Also handle loopback connections in bearer management + * Drop include path for qmqtt, not needed any more + * Fix app logging not working when the cache dir does not exist. + * Fix a crash when a graphview is updated with the very first value + * Fix the back button in the login page + * Update box name for cloud devices + + -- Jenkins Wed, 19 Jun 2019 01:10:16 +0200 + +nymea-app (1.0.126) bionic; urgency=medium + + [ Michael Zanetti ] + * Use KDAB's openssl builds + + -- Jenkins Thu, 13 Jun 2019 01:42:27 +0200 + +nymea-app (1.0.125) bionic; urgency=medium + + [ Michael Zanetti ] + * Update firebase dependency + + -- Jenkins Wed, 12 Jun 2019 17:08:35 +0200 + +nymea-app (1.0.124) bionic; urgency=medium + + [ Michael Zanetti ] + * Link proper libssl arch + + -- Jenkins Wed, 12 Jun 2019 15:24:09 +0200 + +nymea-app (1.0.123) bionic; urgency=medium + + [ Michael Zanetti ] + * Make it build with arm64 + * Add missing dependency to qml-module-qtgraphicaleffects + * Add support for device settings + + -- Jenkins Wed, 12 Jun 2019 12:30:36 +0200 + +nymea-app (1.0.122) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix the crash when opening and closing tabs + + -- Jenkins Thu, 06 Jun 2019 03:20:59 +0200 + +nymea-app (1.0.121) bionic; urgency=medium + + [ Michael Zanetti ] + * Fix a crash when a delayed reply would call a callback for an object + … + * Add missing dependency to qtcharts + + -- Jenkins Thu, 30 May 2019 15:30:00 +0200 + +nymea-app (1.0.120) bionic; urgency=medium + + [ Michael Zanetti ] + * Implement network management + + -- Jenkins Fri, 24 May 2019 03:24:57 +0200 + +nymea-app (1.0.119) bionic; urgency=medium + + [ Michael Zanetti ] + * Improve Kiosk experience + + -- Jenkins Wed, 22 May 2019 15:56:09 +0200 + +nymea-app (1.0.118) bionic; urgency=medium + + [ Michael Zanetti ] + * Add a kiosk dpkg package + + -- Jenkins Tue, 21 May 2019 22:46:37 +0200 + +nymea-app (1.0.117) bionic; urgency=medium + + [ Michael Zanetti ] + * Improved system update mechanism + + -- Jenkins Tue, 21 May 2019 18:14:28 +0200 + +nymea-app (1.0.116) bionic; urgency=medium + + [ Michael Zanetti ] + * System controller + * Add support for the closablesensor interface + * Fix labels overflowing for long state values + * Add some better debug prints + + -- Jenkins Sat, 18 May 2019 02:38:42 +0200 + +nymea-app (1.0.115) bionic; urgency=medium + + [ Michael Zanetti ] + * Prefer http over https for the debug interface to ease up things + + -- Jenkins Wed, 24 Apr 2019 12:54:25 +0200 + +nymea-app (1.0.114) bionic; urgency=medium + + [ Michael Zanetti ] + * Add a kiosk mode command line option + * Fix the kiosk systemd service + * State based ruleactionparams + + -- Jenkins Tue, 16 Apr 2019 01:33:12 +0200 + +nymea-app (1.0.113) bionic; urgency=medium + + [ Michael Zanetti ] + * Add Ubuntu packaging + + -- Jenkins Mon, 15 Apr 2019 22:32:16 +0200 + +nymea-app (1.0.112) bionic; urgency=medium + + * Initial release. + + -- Michael Zanetti Sun, 14 Apr 2019 23:06:13 +0200 diff --git a/packaging/ubuntu/debian/compat b/packaging/ubuntu/debian-qt5/compat similarity index 100% rename from packaging/ubuntu/debian/compat rename to packaging/ubuntu/debian-qt5/compat diff --git a/packaging/ubuntu/debian/control b/packaging/ubuntu/debian-qt5/control similarity index 100% rename from packaging/ubuntu/debian/control rename to packaging/ubuntu/debian-qt5/control diff --git a/packaging/ubuntu/debian/copyright b/packaging/ubuntu/debian-qt5/copyright similarity index 100% rename from packaging/ubuntu/debian/copyright rename to packaging/ubuntu/debian-qt5/copyright diff --git a/packaging/ubuntu/debian/nymea-app-kiosk-wayland.install b/packaging/ubuntu/debian-qt5/nymea-app-kiosk-wayland.install similarity index 100% rename from packaging/ubuntu/debian/nymea-app-kiosk-wayland.install rename to packaging/ubuntu/debian-qt5/nymea-app-kiosk-wayland.install diff --git a/packaging/ubuntu/debian/nymea-app-kiosk-wayland.postinst b/packaging/ubuntu/debian-qt5/nymea-app-kiosk-wayland.postinst similarity index 100% rename from packaging/ubuntu/debian/nymea-app-kiosk-wayland.postinst rename to packaging/ubuntu/debian-qt5/nymea-app-kiosk-wayland.postinst diff --git a/packaging/ubuntu/debian/nymea-app-kiosk-x11.install b/packaging/ubuntu/debian-qt5/nymea-app-kiosk-x11.install similarity index 100% rename from packaging/ubuntu/debian/nymea-app-kiosk-x11.install rename to packaging/ubuntu/debian-qt5/nymea-app-kiosk-x11.install diff --git a/packaging/ubuntu/debian/nymea-app.install b/packaging/ubuntu/debian-qt5/nymea-app.install similarity index 100% rename from packaging/ubuntu/debian/nymea-app.install rename to packaging/ubuntu/debian-qt5/nymea-app.install diff --git a/packaging/ubuntu/debian/nymea-splashscreen.install b/packaging/ubuntu/debian-qt5/nymea-splashscreen.install similarity index 100% rename from packaging/ubuntu/debian/nymea-splashscreen.install rename to packaging/ubuntu/debian-qt5/nymea-splashscreen.install diff --git a/packaging/ubuntu/debian/rules b/packaging/ubuntu/debian-qt5/rules similarity index 100% rename from packaging/ubuntu/debian/rules rename to packaging/ubuntu/debian-qt5/rules diff --git a/packaging/ubuntu/debian/changelog b/packaging/ubuntu/debian-qt6/changelog similarity index 100% rename from packaging/ubuntu/debian/changelog rename to packaging/ubuntu/debian-qt6/changelog diff --git a/packaging/ubuntu/debian-qt6/compat b/packaging/ubuntu/debian-qt6/compat new file mode 100644 index 00000000..ec635144 --- /dev/null +++ b/packaging/ubuntu/debian-qt6/compat @@ -0,0 +1 @@ +9 diff --git a/packaging/ubuntu/debian-qt6/control b/packaging/ubuntu/debian-qt6/control new file mode 100644 index 00000000..e897e970 --- /dev/null +++ b/packaging/ubuntu/debian-qt6/control @@ -0,0 +1,46 @@ +Source: nymea-app +Section: utils +Priority: optional +Maintainer: nymea GmbH +Standards-Version: 4.7.2 +Homepage: https://nymea.io +Vcs-Git: https://github.com/nymea/nymea-app.git +Build-Depends: debhelper, + dpkg-dev, + libavahi-client-dev, + libavahi-common-dev, + qt6-base-dev, + qt6-base-dev-tools, + qt6-connectivity-dev, + qt6-charts-dev, + qt6-svg-dev, + qt6-websockets-dev, + qt6-webview-dev, + qt6-declarative-dev, + libqt6quickcontrols2-6, + +Package: nymea-app +Architecture: any +Section: x11 +Multi-Arch: same +Depends: ${shlibs:Depends}, + ${misc:Depends}, + libqt5network5, + libqt5gui5, + libqt5websockets5, + libqt5bluetooth5, + qml-module-qt-labs-calendar, + qml-module-qt-labs-folderlistmodel, + qml-module-qt-labs-settings, + qml-module-qtcharts, + qml-module-qtgraphicaleffects, + qml-module-qtquick-controls2, + qml-module-qtquick-layouts, + qml-module-qtquick-window2, + qml-module-qtquick2, +Recommends: qml-module-qtwebview, +Suggests: nymea, + network-manager +Description: A client app for nymea + This package will install nymea:app, the client app + and main user interface for nymea:core. diff --git a/packaging/ubuntu/debian-qt6/nymea-app-kiosk-wayland.install b/packaging/ubuntu/debian-qt6/nymea-app-kiosk-wayland.install new file mode 100644 index 00000000..2b84dd7c --- /dev/null +++ b/packaging/ubuntu/debian-qt6/nymea-app-kiosk-wayland.install @@ -0,0 +1,2 @@ +packaging/linux-common/nymea-app-kiosk.service /lib/systemd/system/ +packaging/linux-common/udev/90-pi-backlight.rules /lib/udev/rules.d/ diff --git a/packaging/ubuntu/debian-qt6/nymea-app-kiosk-wayland.postinst b/packaging/ubuntu/debian-qt6/nymea-app-kiosk-wayland.postinst new file mode 100644 index 00000000..9aad2334 --- /dev/null +++ b/packaging/ubuntu/debian-qt6/nymea-app-kiosk-wayland.postinst @@ -0,0 +1,17 @@ +#!/bin/sh + +# Restart nymea-app after update if it's running +systemctl daemon-reload +systemctl status nymea-app-kiosk > /dev/null 2>&1 +if [ $? -eq 0 ]; then + systemctl restart nymea-app-kiosk + if [ $? -eq 0 ]; then + echo "Successfully restarted nymea app kiosk." + else + echo "FAILED to restart nymea app kiosk." + fi +fi + +#DEBHELPER# + +exit 0 diff --git a/packaging/ubuntu/debian-qt6/nymea-app-kiosk-x11.install b/packaging/ubuntu/debian-qt6/nymea-app-kiosk-x11.install new file mode 100644 index 00000000..ec2e1b2f --- /dev/null +++ b/packaging/ubuntu/debian-qt6/nymea-app-kiosk-x11.install @@ -0,0 +1,5 @@ +packaging/linux-common/nymea-app-kiosk.desktop /usr/share/xsessions/ +packaging/linux-common/lightdm/60-nymea-app-kiosk.conf /usr/share/lightdm/lightdm.conf.d/ +packaging/linux-common/nymea-app-kiosk-wrapper /usr/bin/ +packaging/linux-common/nymea-app-session /usr/bin/ +packaging/linux-common/udev/90-pi-backlight.rules /lib/udev/rules.d/ diff --git a/packaging/ubuntu/debian-qt6/nymea-app.install b/packaging/ubuntu/debian-qt6/nymea-app.install new file mode 100644 index 00000000..a08b219e --- /dev/null +++ b/packaging/ubuntu/debian-qt6/nymea-app.install @@ -0,0 +1,3 @@ +usr/bin/nymea-app +usr/share/applications/nymea-app.desktop +usr/share/icons/* diff --git a/packaging/ubuntu/debian-qt6/nymea-splashscreen.install b/packaging/ubuntu/debian-qt6/nymea-splashscreen.install new file mode 100644 index 00000000..5bfae213 --- /dev/null +++ b/packaging/ubuntu/debian-qt6/nymea-splashscreen.install @@ -0,0 +1,2 @@ +packaging/linux-common/nymea-splashscreen.service /lib/systemd/system/ +packaging/linux-common/nymea-splash.png /usr/share/nymea-splashscreen/ diff --git a/packaging/ubuntu/debian-qt6/rules b/packaging/ubuntu/debian-qt6/rules new file mode 100755 index 00000000..71262a39 --- /dev/null +++ b/packaging/ubuntu/debian-qt6/rules @@ -0,0 +1,10 @@ +#!/usr/bin/make -f +# -*- makefile -*- + +export DH_VERBOSE=1 + +override_dh_missing: + dh_missing --fail-missing + +%: + dh $@ --buildsystem=qmake --parallel --with systemd diff --git a/shared.pri b/shared.pri index ba3d9ee9..8b5e8981 100644 --- a/shared.pri +++ b/shared.pri @@ -1,6 +1,17 @@ -CONFIG *= c++14 -QMAKE_LFLAGS *= -std=c++14 -QMAKE_CXXFLAGS *= -std=c++14 +greaterThan(QT_MAJOR_VERSION, 5) { + message("Building using Qt6 support") + CONFIG *= c++17 + QMAKE_LFLAGS *= -std=c++17 + QMAKE_CXXFLAGS *= -std=c++17 +} else { + message("Building using Qt5 support") + CONFIG *= c++14 + QMAKE_LFLAGS *= -std=c++14 + QMAKE_CXXFLAGS *= -std=c++14 + DEFINES += QT_DISABLE_DEPRECATED_UP_TO=0x050F00 +} + +QMAKE_CXXFLAGS *= -Werror -g -Wno-deprecated-declarations top_srcdir=$$PWD top_builddir=$$shadowed($$PWD) @@ -26,10 +37,7 @@ INCLUDEPATH += $${top_builddir} # On Windows, -Wall goes mental, so not using it there !win32:QMAKE_CXXFLAGS += -Wall -# As of Qt 5.15, lots of things are deprecated inside Qt in preparation for Qt6 but no replacement to actually fix those yet. -linux:!android { - QMAKE_CXXFLAGS += -Wno-deprecated-declarations -Wno-deprecated-copy -} +QMAKE_CXXFLAGS += -Wno-deprecated-declarations -Wno-deprecated-copy android: { QMAKE_CXXFLAGS += -Wno-deprecated-declarations From 315ffff367589ccbef761228be32eeb5737d2d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Sun, 16 Nov 2025 13:52:37 +0100 Subject: [PATCH 03/50] Update .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index a892d263..d5b58a47 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,7 @@ Thumbs.db *.pro.user* +CMakeLists.txt.user + packaging/android/nymeaapp.properties build From 1034c415419c3f4db60d22af0cea5817add286b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 24 Nov 2025 11:24:51 +0100 Subject: [PATCH 04/50] Bump version to 1.11.0 --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 72d8e1e7..e5877f29 100644 --- a/version.txt +++ b/version.txt @@ -1,2 +1,2 @@ -1.10.21 +1.11.0 679 From ea72e5c7ea8259b0c43337a3c1805dd22a9af445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 24 Nov 2025 22:21:24 +0100 Subject: [PATCH 05/50] Fix QmlListView crash in ConsumerStats --- nymea-app/ui/mainviews/energy/ConsumerStats.qml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/nymea-app/ui/mainviews/energy/ConsumerStats.qml b/nymea-app/ui/mainviews/energy/ConsumerStats.qml index b2ce8acf..60c3d855 100644 --- a/nymea-app/ui/mainviews/energy/ConsumerStats.qml +++ b/nymea-app/ui/mainviews/energy/ConsumerStats.qml @@ -557,9 +557,16 @@ StatsBase { for (var i = 0; i < consumersRepeater.count; i++) { var consumerDelegate = consumersRepeater.itemAt(i) var consumer = consumerDelegate.thing + if (!consumer) { + continue; + } + var barSet = consumerDelegate.barSet + if (!barSet || barSet.count <= toolTip.idx) { + continue; + } var entry = { consumer: consumer, - value: consumersRepeater.itemAt(i).barSet.at(toolTip.idx).toFixed(2), + value: barSet.at(toolTip.idx).toFixed(2), indexInModel: i } unsorted.push(entry) From dd996d08e1b82d0cb778ef1d00f3ced2cefc9ac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Fri, 21 Nov 2025 13:17:22 +0100 Subject: [PATCH 06/50] iOS: Fix all introduced warnings and port iOS code to Qt 6 iOS: Fix app screen safearea from all directions --- .../airconditioning/temperatureschedule.cpp | 2 +- .../airconditioning/temperatureschedule.h | 4 +- experiences/airconditioning/zoneinfo.cpp | 4 +- experiences/airconditioning/zoneinfo.h | 2 +- libnymea-app/applogcontroller.cpp | 6 +- libnymea-app/configuration/mqttpolicies.cpp | 16 +-- .../configuration/serverconfigurations.cpp | 12 +-- .../connection/discovery/upnpdiscovery.cpp | 2 +- libnymea-app/connection/nymeahost.cpp | 8 +- libnymea-app/connection/nymeahosts.cpp | 10 +- libnymea-app/energy/energylogs.cpp | 23 +++-- libnymea-app/interfacesmodel.cpp | 6 +- libnymea-app/jsonrpc/jsonrpcclient.cpp | 2 +- libnymea-app/modbus/modbusrtumasters.cpp | 20 ++-- libnymea-app/models/boolseriesadapter.cpp | 4 +- libnymea-app/models/logsmodel.cpp | 6 +- libnymea-app/models/logsmodelng.cpp | 7 +- libnymea-app/models/newlogsmodel.cpp | 14 +-- libnymea-app/models/taglistmodel.cpp | 6 +- libnymea-app/models/thingmodel.cpp | 2 +- .../ruletemplates/calendaritemtemplate.h | 4 +- .../ruletemplates/eventdescriptortemplate.h | 4 +- .../ruletemplates/ruleactionparamtemplate.h | 4 +- .../ruletemplates/ruleactiontemplate.h | 4 +- libnymea-app/ruletemplates/ruletemplates.cpp | 2 +- .../ruletemplates/stateevaluatortemplate.h | 4 +- .../ruletemplates/timeeventitemtemplate.h | 4 +- libnymea-app/scripting/completionmodel.cpp | 6 +- .../serverdebug/serverloggingcategories.cpp | 4 +- libnymea-app/thingclasses.cpp | 6 +- libnymea-app/thingdiscovery.cpp | 4 +- libnymea-app/things.cpp | 16 +-- libnymea-app/types/actiontypes.cpp | 4 +- libnymea-app/types/browseritems.cpp | 6 +- libnymea-app/types/calendaritems.cpp | 4 +- libnymea-app/types/eventdescriptors.cpp | 4 +- libnymea-app/types/eventtypes.cpp | 4 +- libnymea-app/types/interfaces.cpp | 2 +- libnymea-app/types/ioconnections.cpp | 4 +- libnymea-app/types/networkdevices.cpp | 10 +- libnymea-app/types/packages.cpp | 16 +-- libnymea-app/types/paramdescriptors.cpp | 4 +- libnymea-app/types/params.cpp | 8 +- libnymea-app/types/paramtypes.cpp | 4 +- libnymea-app/types/plugins.cpp | 6 +- libnymea-app/types/repositories.cpp | 6 +- libnymea-app/types/ruleactionparams.cpp | 4 +- libnymea-app/types/ruleactions.cpp | 4 +- libnymea-app/types/rules.cpp | 6 +- libnymea-app/types/scripts.cpp | 6 +- libnymea-app/types/serialports.cpp | 4 +- libnymea-app/types/stateevaluators.cpp | 4 +- libnymea-app/types/states.cpp | 6 +- libnymea-app/types/statetype.cpp | 2 +- libnymea-app/types/statetypes.cpp | 4 +- libnymea-app/types/tags.cpp | 10 +- libnymea-app/types/timeeventitems.cpp | 4 +- libnymea-app/types/tokeninfos.cpp | 4 +- libnymea-app/types/vendors.cpp | 4 +- libnymea-app/types/wirelessaccesspoints.cpp | 12 +-- libnymea-app/usermanager.cpp | 10 +- .../wifisetup/bluetoothdeviceinfos.cpp | 8 +- libnymea-app/zigbee/zigbeeadapters.cpp | 16 +-- libnymea-app/zigbee/zigbeenetworks.cpp | 30 +++--- libnymea-app/zigbee/zigbeenodes.cpp | 24 ++--- libnymea-app/zwave/zwavenetwork.cpp | 6 +- libnymea-app/zwave/zwavenode.cpp | 4 +- nymea-app/configuredhostsmodel.cpp | 13 +-- nymea-app/dashboard/dashboardmodel.cpp | 12 +-- nymea-app/main.cpp | 13 +++ nymea-app/nfcthingactionwriter.cpp | 3 +- nymea-app/nymea-app.pro | 12 ++- nymea-app/platformhelper.cpp | 34 ++++++- nymea-app/platformhelper.h | 18 +++- .../ios/platformhelperios.cpp | 24 ++++- .../ios/platformhelperios.h | 3 + .../ios/platformhelperios.mm | 99 ++++++++++++++++--- .../ios/platformpermissionsios.cpp | 2 + .../ios/platformpermissionsios.mm | 2 +- nymea-app/ui/Nymea.qml | 4 +- 80 files changed, 432 insertions(+), 279 deletions(-) diff --git a/experiences/airconditioning/temperatureschedule.cpp b/experiences/airconditioning/temperatureschedule.cpp index 7c2a57f5..be04888b 100644 --- a/experiences/airconditioning/temperatureschedule.cpp +++ b/experiences/airconditioning/temperatureschedule.cpp @@ -131,7 +131,7 @@ void TemperatureDaySchedule::clear() void TemperatureDaySchedule::addSchedule(TemperatureSchedule *schedule) { schedule->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(schedule); endInsertRows(); emit countChanged(); diff --git a/experiences/airconditioning/temperatureschedule.h b/experiences/airconditioning/temperatureschedule.h index 3df4e804..bef2e7d1 100644 --- a/experiences/airconditioning/temperatureschedule.h +++ b/experiences/airconditioning/temperatureschedule.h @@ -75,7 +75,7 @@ public: TemperatureDaySchedule(QObject *parent = nullptr); ~TemperatureDaySchedule(); - int rowCount(const QModelIndex & = QModelIndex()) const override { return m_list.count(); } + int rowCount(const QModelIndex & = QModelIndex()) const override { return static_cast(m_list.count()); } QVariant data(const QModelIndex &index, int role) const override; QHash roleNames() const override; @@ -101,7 +101,7 @@ public: TemperatureWeekSchedule(QObject *parent = nullptr); ~TemperatureWeekSchedule(); - int rowCount(const QModelIndex & = QModelIndex()) const override { return m_list.count(); } + int rowCount(const QModelIndex & = QModelIndex()) const override { return static_cast(m_list.count()); } QVariant data(const QModelIndex &, int) const override { return QVariant(); } QHash roleNames() const override { return QHash(); } diff --git a/experiences/airconditioning/zoneinfo.cpp b/experiences/airconditioning/zoneinfo.cpp index 1bcd09ef..309d2a66 100644 --- a/experiences/airconditioning/zoneinfo.cpp +++ b/experiences/airconditioning/zoneinfo.cpp @@ -258,10 +258,10 @@ void ZoneInfos::addZoneInfo(ZoneInfo *zoneInfo) { zoneInfo->setParent(this); connect(zoneInfo, &ZoneInfo::nameChanged, this, [=](){ - QModelIndex idx = index(m_list.indexOf(zoneInfo)); + QModelIndex idx = index(static_cast(m_list.indexOf(zoneInfo))); emit dataChanged(idx, idx, {RoleName}); }); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(zoneInfo); endInsertRows(); emit countChanged(); diff --git a/experiences/airconditioning/zoneinfo.h b/experiences/airconditioning/zoneinfo.h index 4bc46390..9b8e86ea 100644 --- a/experiences/airconditioning/zoneinfo.h +++ b/experiences/airconditioning/zoneinfo.h @@ -173,7 +173,7 @@ public: }; ZoneInfos(QObject *parent = nullptr): QAbstractListModel(parent) {} - int rowCount(const QModelIndex & = QModelIndex()) const override { return m_list.count(); } + int rowCount(const QModelIndex & = QModelIndex()) const override { return static_cast(m_list.count()); } QVariant data(const QModelIndex &index, int role) const override; QHash roleNames() const override; diff --git a/libnymea-app/applogcontroller.cpp b/libnymea-app/applogcontroller.cpp index 0a6ab76c..a1692025 100644 --- a/libnymea-app/applogcontroller.cpp +++ b/libnymea-app/applogcontroller.cpp @@ -308,7 +308,7 @@ LogMessages::LogMessages(QObject *parent): int LogMessages::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_messages.count(); + return static_cast(m_messages.count()); } QVariant LogMessages::data(const QModelIndex &index, int role) const @@ -342,7 +342,7 @@ QHash LogMessages::roleNames() const void LogMessages::append(const QDateTime ×tamp, const QString &category, const QString &message, AppLogController::LogLevel level) { - beginInsertRows(QModelIndex(), m_messages.count(), m_messages.count()); + beginInsertRows(QModelIndex(), static_cast(m_messages.count()), static_cast(m_messages.count())); LogMessage msg; msg.timestamp = timestamp; msg.category = category; @@ -372,7 +372,7 @@ LoggingCategories::LoggingCategories(AppLogController *parent): int LoggingCategories::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return nymeaLoggingCategories().count(); + return static_cast(nymeaLoggingCategories().count()); } QVariant LoggingCategories::data(const QModelIndex &index, int role) const diff --git a/libnymea-app/configuration/mqttpolicies.cpp b/libnymea-app/configuration/mqttpolicies.cpp index 9b44117c..5faf8c37 100644 --- a/libnymea-app/configuration/mqttpolicies.cpp +++ b/libnymea-app/configuration/mqttpolicies.cpp @@ -33,7 +33,7 @@ MqttPolicies::MqttPolicies(QObject *parent) : QAbstractListModel(parent) int MqttPolicies::rowCount(const QModelIndex &index) const { Q_UNUSED(index) - return m_list.count(); + return static_cast(m_list.count()); } QVariant MqttPolicies::data(const QModelIndex &index, int role) const @@ -67,27 +67,27 @@ QHash MqttPolicies::roleNames() const void MqttPolicies::addPolicy(MqttPolicy *policy) { policy->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(policy); connect(policy, &MqttPolicy::clientIdChanged, this, [this, policy]() { - QModelIndex index = this->index(m_list.indexOf(policy)); + QModelIndex index = this->index(static_cast(m_list.indexOf(policy))); emit dataChanged(index, index, {RoleClientId}); }); connect(policy, &MqttPolicy::usernameChanged, this, [this, policy]() { - QModelIndex index = this->index(m_list.indexOf(policy)); + QModelIndex index = this->index(static_cast(m_list.indexOf(policy))); emit dataChanged(index, index, {RoleUsername}); }); connect(policy, &MqttPolicy::passwordChanged, this, [this, policy]() { - QModelIndex index = this->index(m_list.indexOf(policy)); + QModelIndex index = this->index(static_cast(m_list.indexOf(policy))); emit dataChanged(index, index, {RolePassword}); }); connect(policy, &MqttPolicy::allowedPublishTopicFiltersChanged, this, [this, policy]() { - QModelIndex index = this->index(m_list.indexOf(policy)); + QModelIndex index = this->index(static_cast(m_list.indexOf(policy))); emit dataChanged(index, index, {RoleAllowedPublishTopicFilters}); }); connect(policy, &MqttPolicy::allowedSubscribeTopicFiltersChanged, this, [this, policy]() { - QModelIndex index = this->index(m_list.indexOf(policy)); + QModelIndex index = this->index(static_cast(m_list.indexOf(policy))); emit dataChanged(index, index, {RoleAllowedSubscribeTopicFilters}); }); @@ -97,7 +97,7 @@ void MqttPolicies::addPolicy(MqttPolicy *policy) void MqttPolicies::removePolicy(MqttPolicy *policy) { - int idx = m_list.indexOf(policy); + int idx = static_cast(m_list.indexOf(policy)); if (idx < 0) { return; } diff --git a/libnymea-app/configuration/serverconfigurations.cpp b/libnymea-app/configuration/serverconfigurations.cpp index 4901b666..cb7ba2af 100644 --- a/libnymea-app/configuration/serverconfigurations.cpp +++ b/libnymea-app/configuration/serverconfigurations.cpp @@ -33,7 +33,7 @@ ServerConfigurations::ServerConfigurations(QObject *parent) : QAbstractListModel int ServerConfigurations::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant ServerConfigurations::data(const QModelIndex &index, int role) const @@ -67,23 +67,23 @@ QHash ServerConfigurations::roleNames() const void ServerConfigurations::addConfiguration(ServerConfiguration *configuration) { configuration->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(configuration); connect(configuration, &ServerConfiguration::addressChanged, this, [this, configuration]() { - QModelIndex idx = index(m_list.indexOf(configuration), 0); + QModelIndex idx = index(static_cast(m_list.indexOf(configuration)), 0); emit dataChanged(idx, idx, {RoleAddress}); }); connect(configuration, &ServerConfiguration::portChanged, this, [this, configuration]() { - QModelIndex idx = index(m_list.indexOf(configuration), 0); + QModelIndex idx = index(static_cast(m_list.indexOf(configuration)), 0); emit dataChanged(idx, idx, {RolePort}); }); connect(configuration, &ServerConfiguration::authenticationEnabledChanged, this, [this, configuration]() { - QModelIndex idx = index(m_list.indexOf(configuration), 0); + QModelIndex idx = index(static_cast(m_list.indexOf(configuration)), 0); emit dataChanged(idx, idx, {RoleAuthenticationEnabled}); }); connect(configuration, &ServerConfiguration::sslEnabledChanged, this, [this, configuration]() { - QModelIndex idx = index(m_list.indexOf(configuration), 0); + QModelIndex idx = index(static_cast(m_list.indexOf(configuration)), 0); emit dataChanged(idx, idx, {RoleSslEnabled}); }); diff --git a/libnymea-app/connection/discovery/upnpdiscovery.cpp b/libnymea-app/connection/discovery/upnpdiscovery.cpp index 42310675..5a709bbf 100644 --- a/libnymea-app/connection/discovery/upnpdiscovery.cpp +++ b/libnymea-app/connection/discovery/upnpdiscovery.cpp @@ -181,7 +181,7 @@ void UpnpDiscovery::readData() const QStringList lines = QString(data).split("\r\n"); foreach (const QString& line, lines) { - int separatorIndex = line.indexOf(':'); + int separatorIndex = static_cast(line.indexOf(':')); QString key = line.left(separatorIndex).toUpper(); QString value = line.mid(separatorIndex+1).trimmed(); diff --git a/libnymea-app/connection/nymeahost.cpp b/libnymea-app/connection/nymeahost.cpp index 341baa9a..2f9626a8 100644 --- a/libnymea-app/connection/nymeahost.cpp +++ b/libnymea-app/connection/nymeahost.cpp @@ -126,7 +126,7 @@ Connections::~Connections() int Connections::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_connections.count(); + return static_cast(m_connections.count()); } QVariant Connections::data(const QModelIndex &index, int role) const @@ -159,10 +159,10 @@ Connection* Connections::find(const QUrl &url) const void Connections::addConnection(Connection *connection) { connection->setParent(this); - beginInsertRows(QModelIndex(), m_connections.count(), m_connections.count()); + beginInsertRows(QModelIndex(), static_cast(m_connections.count()), static_cast(m_connections.count())); m_connections.append(connection); connect(connection, &Connection::onlineChanged, this, [this, connection]() { - int idx = m_connections.indexOf(connection); + int idx = static_cast(m_connections.indexOf(connection)); if (idx < 0) { return; } @@ -175,7 +175,7 @@ void Connections::addConnection(Connection *connection) void Connections::removeConnection(Connection *connection) { - int idx = m_connections.indexOf(connection); + int idx = static_cast(m_connections.indexOf(connection)); if (idx == -1) { qWarning() << "Cannot remove connections as it's not in this model"; return; diff --git a/libnymea-app/connection/nymeahosts.cpp b/libnymea-app/connection/nymeahosts.cpp index cea61434..8c821a40 100644 --- a/libnymea-app/connection/nymeahosts.cpp +++ b/libnymea-app/connection/nymeahosts.cpp @@ -35,7 +35,7 @@ NymeaHosts::NymeaHosts(QObject *parent) : int NymeaHosts::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_hosts.count(); + return static_cast(m_hosts.count()); } QVariant NymeaHosts::data(const QModelIndex &index, int role) const @@ -65,16 +65,16 @@ void NymeaHosts::addHost(NymeaHost *host) } host->setParent(this); connect(host, &NymeaHost::nameChanged, this, [=](){ - int idx = m_hosts.indexOf(host); + int idx = static_cast(m_hosts.indexOf(host)); emit dataChanged(index(idx), index(idx), {NameRole}); }); connect(host, &NymeaHost::versionChanged, this, [=](){ - int idx = m_hosts.indexOf(host); + int idx = static_cast(m_hosts.indexOf(host)); emit dataChanged(index(idx), index(idx), {VersionRole}); }); connect(host, &NymeaHost::connectionChanged, this, &NymeaHosts::hostChanged); - beginInsertRows(QModelIndex(), m_hosts.count(), m_hosts.count()); + beginInsertRows(QModelIndex(), static_cast(m_hosts.count()), static_cast(m_hosts.count())); m_hosts.append(host); endInsertRows(); emit hostAdded(host); @@ -83,7 +83,7 @@ void NymeaHosts::addHost(NymeaHost *host) void NymeaHosts::removeHost(NymeaHost *host) { - int idx = m_hosts.indexOf(host); + int idx = static_cast(m_hosts.indexOf(host)); if (idx == -1) { qWarning() << "Cannot remove NymeaHost" << host << "as its not in the model"; return; diff --git a/libnymea-app/energy/energylogs.cpp b/libnymea-app/energy/energylogs.cpp index 2ae67be8..12d6de36 100644 --- a/libnymea-app/energy/energylogs.cpp +++ b/libnymea-app/energy/energylogs.cpp @@ -183,7 +183,7 @@ void EnergyLogs::componentComplete() int EnergyLogs::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant EnergyLogs::data(const QModelIndex &index, int role) const @@ -267,7 +267,7 @@ QList EnergyLogs::entries() const void EnergyLogs::appendEntry(EnergyLogEntry *entry, double minValue, double maxValue) { entry->setParent(this); - int index = m_list.count(); + int index = static_cast(m_list.count()); beginInsertRows(QModelIndex(), index, index); m_list.append(entry); endInsertRows(); @@ -286,8 +286,8 @@ void EnergyLogs::appendEntry(EnergyLogEntry *entry, double minValue, double maxV void EnergyLogs::appendEntries(const QList &entries) { - int index = m_list.count(); - beginInsertRows(QModelIndex(), index, index + entries.count()); + int index = static_cast(m_list.count()); + beginInsertRows(QModelIndex(), index, index + static_cast(entries.count())); for (int i = 0; i < entries.count(); i++) { EnergyLogEntry* entry = entries.at(i); entry->setParent(this); @@ -316,7 +316,7 @@ void EnergyLogs::getLogsResponse(int commandId, const QVariantMap ¶ms) if (!entries.isEmpty()) { if (m_list.isEmpty()) { // qCDebug(dcEnergyLogs()) << "Energy logs received" << qUtf8Printable(QJsonDocument::fromVariant(params).toJson()); - beginInsertRows(QModelIndex(), 0, entries.count()); + beginInsertRows(QModelIndex(), 0, static_cast(entries.count())); m_list.append(entries); endInsertRows(); emit entriesAdded(0, entries); @@ -328,7 +328,7 @@ void EnergyLogs::getLogsResponse(int commandId, const QVariantMap ¶ms) } else if (entries.first()->timestamp() < m_list.first()->timestamp()) { if (entries.last()->timestamp().addSecs(m_sampleRate * 60) == m_list.first()->timestamp()) { - beginInsertRows(QModelIndex(), 0, entries.count()); + beginInsertRows(QModelIndex(), 0, static_cast(entries.count())); m_list = entries + m_list; endInsertRows(); emit entriesAdded(0, entries); @@ -348,7 +348,7 @@ void EnergyLogs::getLogsResponse(int commandId, const QVariantMap ¶ms) // If the mismatch is in the visible area, we'll discard everything and fetch again // Else if the mismatch is outside the visible area, we'll just discard the old data and work with what we received if (entries.first()->timestamp() <= m_startTime && entries.last()->timestamp() >= m_endTime) { - beginInsertRows(QModelIndex(), 0, entries.count()); + beginInsertRows(QModelIndex(), 0, static_cast(entries.count())); m_list.append(entries); endInsertRows(); emit entriesAdded(0, entries); @@ -363,8 +363,8 @@ void EnergyLogs::getLogsResponse(int commandId, const QVariantMap ¶ms) } } else if (entries.first()->timestamp().addSecs(-m_sampleRate * 60) == m_list.last()->timestamp()) { - int index = m_list.count(); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count() + entries.count()); + int index = static_cast(m_list.count()); + beginInsertRows(QModelIndex(), index, index + static_cast(entries.count())); m_list.append(entries); endInsertRows(); emit entriesAdded(index, entries); @@ -379,7 +379,7 @@ void EnergyLogs::getLogsResponse(int commandId, const QVariantMap ¶ms) } else { // Start of fetched entries does not line up with end of existing entries. Discarding existing entries clear(); - beginInsertRows(QModelIndex(), 0, entries.count()); + beginInsertRows(QModelIndex(), 0, static_cast(entries.count())); m_list.append(entries); endInsertRows(); emit entriesAdded(0, entries); @@ -420,7 +420,7 @@ void EnergyLogs::notificationReceivedInternal(const QVariantMap &data) void EnergyLogs::clear() { - int count = m_list.count(); + int count = static_cast(m_list.count()); beginResetModel(); qDeleteAll(m_list); m_list.clear(); @@ -486,4 +486,3 @@ void EnergyLogs::fetchLogs() qCDebug(dcEnergyLogs()) << "Fetching energy logs:" << qUtf8Printable(QJsonDocument::fromVariant(params).toJson()); m_engine->jsonRpcClient()->sendCommand("Energy.Get" + logsName(), params, this, "getLogsResponse"); } - diff --git a/libnymea-app/interfacesmodel.cpp b/libnymea-app/interfacesmodel.cpp index e91a5067..c0293659 100644 --- a/libnymea-app/interfacesmodel.cpp +++ b/libnymea-app/interfacesmodel.cpp @@ -36,7 +36,7 @@ InterfacesModel::InterfacesModel(QObject *parent): int InterfacesModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_interfaces.count(); + return static_cast(m_interfaces.count()); } QVariant InterfacesModel::data(const QModelIndex &index, int role) const @@ -185,13 +185,13 @@ void InterfacesModel::syncInterfaces() interfacesToAdd.removeAll(interface); } foreach (const QString &interface, interfacesToRemove) { - int idx = m_interfaces.indexOf(interface); + int idx = static_cast(m_interfaces.indexOf(interface)); beginRemoveRows(QModelIndex(), idx, idx); m_interfaces.takeAt(idx); endRemoveRows(); } if (!interfacesToAdd.isEmpty()) { - beginInsertRows(QModelIndex(), m_interfaces.count(), m_interfaces.count() + interfacesToAdd.count() - 1); + beginInsertRows(QModelIndex(), static_cast(m_interfaces.count()), static_cast(m_interfaces.count()) + static_cast(interfacesToAdd.count()) - 1); m_interfaces.append(interfacesToAdd); endInsertRows(); } diff --git a/libnymea-app/jsonrpc/jsonrpcclient.cpp b/libnymea-app/jsonrpc/jsonrpcclient.cpp index 29c317be..f106056a 100644 --- a/libnymea-app/jsonrpc/jsonrpcclient.cpp +++ b/libnymea-app/jsonrpc/jsonrpcclient.cpp @@ -549,7 +549,7 @@ void JsonRpcClient::dataReceived(const QByteArray &data) // qDebug() << "JsonRpcClient: received data:" << qUtf8Printable(data); m_receiveBuffer.append(data); - int splitIndex = m_receiveBuffer.indexOf("}\n{") + 1; + int splitIndex = static_cast(m_receiveBuffer.indexOf("}\n{")) + 1; if (splitIndex <= 0) { splitIndex = m_receiveBuffer.length(); } diff --git a/libnymea-app/modbus/modbusrtumasters.cpp b/libnymea-app/modbus/modbusrtumasters.cpp index ec297d33..b30154ff 100644 --- a/libnymea-app/modbus/modbusrtumasters.cpp +++ b/libnymea-app/modbus/modbusrtumasters.cpp @@ -37,7 +37,7 @@ QList ModbusRtuMasters::modbusRtuMasters() const int ModbusRtuMasters::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_modbusRtuMasters.count(); + return static_cast(m_modbusRtuMasters.count()); } QVariant ModbusRtuMasters::data(const QModelIndex &index, int role) const @@ -86,54 +86,54 @@ void ModbusRtuMasters::addModbusRtuMaster(ModbusRtuMaster *modbusRtuMaster) connect(modbusRtuMaster, &ModbusRtuMaster::serialPortChanged, this, [=](const QString &serialPort) { Q_UNUSED(serialPort) - QModelIndex idx = index(m_modbusRtuMasters.indexOf(modbusRtuMaster), 0); + QModelIndex idx = index(static_cast(m_modbusRtuMasters.indexOf(modbusRtuMaster)), 0); emit dataChanged(idx, idx, {RoleSerialPort}); }); connect(modbusRtuMaster, &ModbusRtuMaster::baudrateChanged, this, [=](qint32 baudrate) { Q_UNUSED(baudrate) - QModelIndex idx = index(m_modbusRtuMasters.indexOf(modbusRtuMaster), 0); + QModelIndex idx = index(static_cast(m_modbusRtuMasters.indexOf(modbusRtuMaster)), 0); emit dataChanged(idx, idx, {RoleBaudrate}); }); connect(modbusRtuMaster, &ModbusRtuMaster::parityChanged, this, [=](SerialPort::SerialPortParity parity) { Q_UNUSED(parity) - QModelIndex idx = index(m_modbusRtuMasters.indexOf(modbusRtuMaster), 0); + QModelIndex idx = index(static_cast(m_modbusRtuMasters.indexOf(modbusRtuMaster)), 0); emit dataChanged(idx, idx, {RoleParity}); }); connect(modbusRtuMaster, &ModbusRtuMaster::dataBitsChanged, this, [=](SerialPort::SerialPortDataBits dataBits) { Q_UNUSED(dataBits) - QModelIndex idx = index(m_modbusRtuMasters.indexOf(modbusRtuMaster), 0); + QModelIndex idx = index(static_cast(m_modbusRtuMasters.indexOf(modbusRtuMaster)), 0); emit dataChanged(idx, idx, {RoleDataBits}); }); connect(modbusRtuMaster, &ModbusRtuMaster::stopBitsChanged, this, [=](SerialPort::SerialPortStopBits stopBites) { Q_UNUSED(stopBites) - QModelIndex idx = index(m_modbusRtuMasters.indexOf(modbusRtuMaster), 0); + QModelIndex idx = index(static_cast(m_modbusRtuMasters.indexOf(modbusRtuMaster)), 0); emit dataChanged(idx, idx, {RoleStopBits}); }); connect(modbusRtuMaster, &ModbusRtuMaster::numberOfRetriesChanged, this, [=](uint numberOfRetries) { Q_UNUSED(numberOfRetries) - QModelIndex idx = index(m_modbusRtuMasters.indexOf(modbusRtuMaster), 0); + QModelIndex idx = index(static_cast(m_modbusRtuMasters.indexOf(modbusRtuMaster)), 0); emit dataChanged(idx, idx, {RoleNumberOfRetries}); }); connect(modbusRtuMaster, &ModbusRtuMaster::timeoutChanged, this, [=](uint timeout) { Q_UNUSED(timeout) - QModelIndex idx = index(m_modbusRtuMasters.indexOf(modbusRtuMaster), 0); + QModelIndex idx = index(static_cast(m_modbusRtuMasters.indexOf(modbusRtuMaster)), 0); emit dataChanged(idx, idx, {RoleTimeout}); }); connect(modbusRtuMaster, &ModbusRtuMaster::connectedChanged, this, [=](bool connected) { Q_UNUSED(connected) - QModelIndex idx = index(m_modbusRtuMasters.indexOf(modbusRtuMaster), 0); + QModelIndex idx = index(static_cast(m_modbusRtuMasters.indexOf(modbusRtuMaster)), 0); emit dataChanged(idx, idx, {RoleConnected}); }); - beginInsertRows(QModelIndex(), m_modbusRtuMasters.count(), m_modbusRtuMasters.count()); + beginInsertRows(QModelIndex(), static_cast(m_modbusRtuMasters.count()), static_cast(m_modbusRtuMasters.count())); m_modbusRtuMasters.append(modbusRtuMaster); endInsertRows(); diff --git a/libnymea-app/models/boolseriesadapter.cpp b/libnymea-app/models/boolseriesadapter.cpp index 37b70cdb..47f31679 100644 --- a/libnymea-app/models/boolseriesadapter.cpp +++ b/libnymea-app/models/boolseriesadapter.cpp @@ -133,14 +133,14 @@ quint64 BoolSeriesAdapter::findIndex(qulonglong timestamp) // In 99.9% of the cases we'll be prepending (adding live entries) or appending (fetching history) if (timestamp < m_series->at(m_series->count() - 2).x()) { - return m_series->count() - 1; + return static_cast(m_series->count() - 1); } if (timestamp > m_series->at(1).x()) { return 1; } // If for any reason a entry in the middle is added (can't think of one but hey), a binary search will probably do. - int idx = m_series->count() / 2; + int idx = static_cast(m_series->count() / 2); int range = idx; int i = 0; while (true) { diff --git a/libnymea-app/models/logsmodel.cpp b/libnymea-app/models/logsmodel.cpp index 5e017103..dcdfa5e6 100644 --- a/libnymea-app/models/logsmodel.cpp +++ b/libnymea-app/models/logsmodel.cpp @@ -62,7 +62,7 @@ void LogsModel::setEngine(Engine *engine) int LogsModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant LogsModel::data(const QModelIndex &index, int role) const @@ -247,7 +247,7 @@ LogEntry *LogsModel::findClosest(const QDateTime &dateTime) return nullptr; } int newest = 0; - int oldest = m_list.count() - 1; + int oldest = static_cast(m_list.count()) - 1; LogEntry *entry = nullptr; int step = 0; @@ -348,7 +348,7 @@ void LogsModel::logsReply(int /*commandId*/, const QVariantMap &data) return; } - beginInsertRows(QModelIndex(), offset, offset + newBlock.count() - 1); + beginInsertRows(QModelIndex(), offset, offset + static_cast(newBlock.count()) - 1); for (int i = 0; i < newBlock.count(); i++) { // qCDebug(dcLogEngine()) << objectName() << "Inserting: list count" << m_list.count() << "blockSize" << newBlock.count() << "insterting at:" << offset + i; LogEntry *entry = newBlock.at(i); diff --git a/libnymea-app/models/logsmodelng.cpp b/libnymea-app/models/logsmodelng.cpp index 419015f9..30e454fd 100644 --- a/libnymea-app/models/logsmodelng.cpp +++ b/libnymea-app/models/logsmodelng.cpp @@ -66,7 +66,7 @@ void LogsModelNg::setEngine(Engine *engine) int LogsModelNg::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant LogsModelNg::data(const QModelIndex &index, int role) const @@ -252,7 +252,7 @@ LogEntry *LogsModelNg::findClosest(const QDateTime &dateTime) const return nullptr; } int newest = 0; - int oldest = m_list.count() - 1; + int oldest = static_cast(m_list.count()) - 1; LogEntry *entry = nullptr; int step = 0; @@ -338,7 +338,7 @@ void LogsModelNg::logsReply(int commandId, const QVariantMap &data) return; } - beginInsertRows(QModelIndex(), offset, offset + newBlock.count() - 1); + beginInsertRows(QModelIndex(), offset, offset + static_cast(newBlock.count()) - 1); QVariant newMin = m_minValue; QVariant newMax = m_maxValue; for (int i = 0; i < newBlock.count(); i++) { @@ -580,4 +580,3 @@ void LogsModelNg::newLogEntryReceived(const QVariantMap &data) } - diff --git a/libnymea-app/models/newlogsmodel.cpp b/libnymea-app/models/newlogsmodel.cpp index cb0197c0..17733488 100644 --- a/libnymea-app/models/newlogsmodel.cpp +++ b/libnymea-app/models/newlogsmodel.cpp @@ -47,7 +47,7 @@ NewLogsModel::NewLogsModel(QObject *parent) int NewLogsModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant NewLogsModel::data(const QModelIndex &index, int role) const @@ -279,8 +279,8 @@ NewLogEntry *NewLogsModel::find(const QDateTime ×tamp) const if (m_list.isEmpty()) { return nullptr; } - int idx = m_list.count() / 2; - int jump = m_list.count() / 4; + int idx = static_cast(m_list.count() / 2); + int jump = static_cast(m_list.count() / 4); int stopper = 10; while (stopper-- > 0) { // qCDebug(dcLogEngine()) << "idx:" << idx << "cnt:" << m_list.count() << "jmp" << jump; @@ -356,7 +356,7 @@ NewLogEntry *NewLogsModel::find(const QDateTime ×tamp) const void NewLogsModel::clear() { - int count = m_list.count(); + int count = static_cast(m_list.count()); beginResetModel(); qDeleteAll(m_list); m_list.clear(); @@ -450,7 +450,7 @@ void NewLogsModel::logsReply(int commandId, const QVariantMap &data) qDeleteAll(oldEntries); if (!entries.isEmpty()) { - beginInsertRows(QModelIndex(), 0, entries.count() - 1); + beginInsertRows(QModelIndex(), 0, static_cast(entries.count()) - 1); m_list = entries; endInsertRows(); } @@ -459,7 +459,7 @@ void NewLogsModel::logsReply(int commandId, const QVariantMap &data) } else { if (!entries.isEmpty()) { - beginInsertRows(QModelIndex(), m_list.count(), m_list.count() + entries.count() - 1); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count()) + static_cast(entries.count()) - 1); std::sort(entries.begin(), entries.end(), [](NewLogEntry *left, NewLogEntry *right){ return left->timestamp() > right->timestamp(); }); @@ -488,7 +488,7 @@ void NewLogsModel::newLogEntryReceived(const QVariantMap &map) endInsertRows(); emit entriesAdded(0, {entry}); } else { - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(entry); endInsertRows(); emit entriesAdded(m_list.count() - 1, {entry}); diff --git a/libnymea-app/models/taglistmodel.cpp b/libnymea-app/models/taglistmodel.cpp index 72f94fcc..f879e7d2 100644 --- a/libnymea-app/models/taglistmodel.cpp +++ b/libnymea-app/models/taglistmodel.cpp @@ -53,7 +53,7 @@ void TagListModel::setTagsProxy(TagsProxyModel *tagsProxy) int TagListModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant TagListModel::data(const QModelIndex &index, int role) const @@ -112,7 +112,7 @@ void TagListModel::update() Tag *t = new Tag(tag->tagId(), tag->value(), this); t->setThingId(tag->thingId()); t->setRuleId(tag->ruleId()); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(t); endInsertRows(); } @@ -130,7 +130,7 @@ void TagListModel::update() } } if (!found) { - int idx = m_list.indexOf(tag); + int idx = static_cast(m_list.indexOf(tag)); beginRemoveRows(QModelIndex(), idx, idx); m_list.at(idx)->deleteLater(); it.remove(); diff --git a/libnymea-app/models/thingmodel.cpp b/libnymea-app/models/thingmodel.cpp index 678fb269..a96beada 100644 --- a/libnymea-app/models/thingmodel.cpp +++ b/libnymea-app/models/thingmodel.cpp @@ -34,7 +34,7 @@ ThingModel::ThingModel(QObject *parent) : QAbstractListModel(parent) int ThingModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant ThingModel::data(const QModelIndex &index, int role) const diff --git a/libnymea-app/ruletemplates/calendaritemtemplate.h b/libnymea-app/ruletemplates/calendaritemtemplate.h index f22cbdaf..13c3f3d7 100644 --- a/libnymea-app/ruletemplates/calendaritemtemplate.h +++ b/libnymea-app/ruletemplates/calendaritemtemplate.h @@ -66,7 +66,7 @@ class CalendarItemTemplates: public QAbstractListModel public: CalendarItemTemplates(QObject *parent = nullptr): QAbstractListModel(parent) {} - int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent); return m_list.count(); } + int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent); return static_cast(m_list.count()); } QVariant data(const QModelIndex &index, int role) const override { Q_UNUSED(index); Q_UNUSED(role); return QVariant(); } Q_INVOKABLE CalendarItemTemplate* get(int index) const { @@ -78,7 +78,7 @@ public: void addCalendarItemTemplate(CalendarItemTemplate *calendarItemTemplate) { calendarItemTemplate->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(calendarItemTemplate); endInsertRows(); } diff --git a/libnymea-app/ruletemplates/eventdescriptortemplate.h b/libnymea-app/ruletemplates/eventdescriptortemplate.h index 7f1327ef..698386a7 100644 --- a/libnymea-app/ruletemplates/eventdescriptortemplate.h +++ b/libnymea-app/ruletemplates/eventdescriptortemplate.h @@ -71,12 +71,12 @@ public: EventDescriptorTemplates(QObject *parent = nullptr): QAbstractListModel(parent) {} QStringList interfaces() const; - int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent); return m_list.count(); } + int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent); return static_cast(m_list.count()); } QVariant data(const QModelIndex &index, int role) const override { Q_UNUSED(index); Q_UNUSED(role); return QVariant(); } void addEventDescriptorTemplate(EventDescriptorTemplate *eventDescriptorTemplate) { eventDescriptorTemplate->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(eventDescriptorTemplate); endInsertRows(); emit countChanged(); diff --git a/libnymea-app/ruletemplates/ruleactionparamtemplate.h b/libnymea-app/ruletemplates/ruleactionparamtemplate.h index c6d7fb26..986643fb 100644 --- a/libnymea-app/ruletemplates/ruleactionparamtemplate.h +++ b/libnymea-app/ruletemplates/ruleactionparamtemplate.h @@ -66,12 +66,12 @@ class RuleActionParamTemplates : public QAbstractListModel public: explicit RuleActionParamTemplates(QObject *parent = nullptr): QAbstractListModel(parent) {} - int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent); return m_list.count(); } + int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent); return static_cast(m_list.count()); } QVariant data(const QModelIndex &index, int role) const override { Q_UNUSED(index) Q_UNUSED(role) return QVariant(); } void addRuleActionParamTemplate(RuleActionParamTemplate *ruleActionParamTemplate) { ruleActionParamTemplate->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(ruleActionParamTemplate); endInsertRows(); emit countChanged(); diff --git a/libnymea-app/ruletemplates/ruleactiontemplate.h b/libnymea-app/ruletemplates/ruleactiontemplate.h index 1c8d28b3..4be39f29 100644 --- a/libnymea-app/ruletemplates/ruleactiontemplate.h +++ b/libnymea-app/ruletemplates/ruleactiontemplate.h @@ -73,13 +73,13 @@ class RuleActionTemplates: public QAbstractListModel Q_PROPERTY(QStringList interfaces READ interfaces CONSTANT) public: RuleActionTemplates(QObject *parent = nullptr): QAbstractListModel(parent) {} - int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent); return m_list.count(); } + int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent); return static_cast(m_list.count()); } QVariant data(const QModelIndex &index, int role) const override { Q_UNUSED(index); Q_UNUSED(role); return QVariant(); } QStringList interfaces() const; void addRuleActionTemplate(RuleActionTemplate* ruleActionTemplate) { ruleActionTemplate->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(ruleActionTemplate); endInsertRows(); emit countChanged(); diff --git a/libnymea-app/ruletemplates/ruletemplates.cpp b/libnymea-app/ruletemplates/ruletemplates.cpp index 3cc8e321..dc264ce1 100644 --- a/libnymea-app/ruletemplates/ruletemplates.cpp +++ b/libnymea-app/ruletemplates/ruletemplates.cpp @@ -187,7 +187,7 @@ RuleTemplates::RuleTemplates(QObject *parent) : QAbstractListModel(parent) int RuleTemplates::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant RuleTemplates::data(const QModelIndex &index, int role) const diff --git a/libnymea-app/ruletemplates/stateevaluatortemplate.h b/libnymea-app/ruletemplates/stateevaluatortemplate.h index d4d04590..2a69047a 100644 --- a/libnymea-app/ruletemplates/stateevaluatortemplate.h +++ b/libnymea-app/ruletemplates/stateevaluatortemplate.h @@ -68,7 +68,7 @@ class StateEvaluatorTemplates: public QAbstractListModel public: StateEvaluatorTemplates(QObject *parent = nullptr): QAbstractListModel(parent) {} - int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent); return m_list.count(); } + int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent); return static_cast(m_list.count()); } QVariant data(const QModelIndex &index, int role) const override { Q_UNUSED(index); Q_UNUSED(role); return QVariant(); } Q_INVOKABLE StateEvaluatorTemplate* get(int index) const { @@ -80,7 +80,7 @@ public: void addStateEvaluatorTemplate(StateEvaluatorTemplate *stateEvaluatorTemplate) { stateEvaluatorTemplate->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(stateEvaluatorTemplate); endInsertRows(); } diff --git a/libnymea-app/ruletemplates/timeeventitemtemplate.h b/libnymea-app/ruletemplates/timeeventitemtemplate.h index 0f51e805..13bdeb74 100644 --- a/libnymea-app/ruletemplates/timeeventitemtemplate.h +++ b/libnymea-app/ruletemplates/timeeventitemtemplate.h @@ -64,7 +64,7 @@ class TimeEventItemTemplates: public QAbstractListModel public: TimeEventItemTemplates(QObject *parent = nullptr): QAbstractListModel(parent) {} - int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent) return m_list.count(); } + int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent) return static_cast(m_list.count()); } QVariant data(const QModelIndex &index, int role) const override { Q_UNUSED(index) Q_UNUSED(role) return QVariant(); } Q_INVOKABLE TimeEventItemTemplate* get(int index) const { @@ -76,7 +76,7 @@ public: void addTimeEventItemTemplate(TimeEventItemTemplate *timeEventItemTemplate) { timeEventItemTemplate->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(timeEventItemTemplate); endInsertRows(); } diff --git a/libnymea-app/scripting/completionmodel.cpp b/libnymea-app/scripting/completionmodel.cpp index 9a01e0f3..fb98b824 100644 --- a/libnymea-app/scripting/completionmodel.cpp +++ b/libnymea-app/scripting/completionmodel.cpp @@ -34,7 +34,7 @@ CompletionModel::CompletionModel(QObject *parent): QAbstractListModel(parent) int CompletionModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QHash CompletionModel::roleNames() const @@ -135,8 +135,8 @@ bool CompletionProxyModel::lessThan(const QModelIndex &source_left, const QModel static QStringList ordering = {"property", "method", "event", "type", "attachedProperty", "keyword" }; - int leftOrder = ordering.indexOf(left.decoration); - int rightOrder = ordering.indexOf(right.decoration); + int leftOrder = static_cast(ordering.indexOf(left.decoration)); + int rightOrder = static_cast(ordering.indexOf(right.decoration)); if (leftOrder != rightOrder) { return leftOrder < rightOrder; diff --git a/libnymea-app/serverdebug/serverloggingcategories.cpp b/libnymea-app/serverdebug/serverloggingcategories.cpp index 13cd4495..1731124c 100644 --- a/libnymea-app/serverdebug/serverloggingcategories.cpp +++ b/libnymea-app/serverdebug/serverloggingcategories.cpp @@ -31,7 +31,7 @@ ServerLoggingCategories::ServerLoggingCategories(QObject *parent) int ServerLoggingCategories::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant ServerLoggingCategories::data(const QModelIndex &index, int role) const @@ -69,7 +69,7 @@ void ServerLoggingCategories::createFromVariantList(const QVariantList &loggingC connect(category, &ServerLoggingCategory::levelChanged, this, [this, category](ServerLoggingCategory::Level level) { Q_UNUSED(level) - QModelIndex idx = index(m_list.indexOf(category), 0); + QModelIndex idx = index(static_cast(static_cast(m_list.indexOf(category))), 0); emit dataChanged(idx, idx, {RoleLevel}); }); diff --git a/libnymea-app/thingclasses.cpp b/libnymea-app/thingclasses.cpp index ca39f6cf..4aa37abf 100644 --- a/libnymea-app/thingclasses.cpp +++ b/libnymea-app/thingclasses.cpp @@ -39,7 +39,7 @@ QList ThingClasses::thingClasses() int ThingClasses::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_thingClasses.count(); + return static_cast(m_thingClasses.count()); } QVariant ThingClasses::data(const QModelIndex &index, int role) const @@ -69,7 +69,7 @@ QVariant ThingClasses::data(const QModelIndex &index, int role) const int ThingClasses::count() const { - return m_thingClasses.count(); + return static_cast(m_thingClasses.count()); } ThingClass *ThingClasses::get(int index) const @@ -93,7 +93,7 @@ ThingClass *ThingClasses::getThingClass(QUuid thingClassId) const void ThingClasses::addThingClass(ThingClass *thingClass) { thingClass->setParent(this); - beginInsertRows(QModelIndex(), m_thingClasses.count(), m_thingClasses.count()); + beginInsertRows(QModelIndex(), static_cast(m_thingClasses.count()), static_cast(m_thingClasses.count())); m_thingClasses.append(thingClass); endInsertRows(); emit countChanged(); diff --git a/libnymea-app/thingdiscovery.cpp b/libnymea-app/thingdiscovery.cpp index f71e5f6b..5e1fe76f 100644 --- a/libnymea-app/thingdiscovery.cpp +++ b/libnymea-app/thingdiscovery.cpp @@ -40,7 +40,7 @@ ThingDiscovery::ThingDiscovery(QObject *parent) : int ThingDiscovery::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_foundThings.count(); + return static_cast(m_foundThings.count()); } QVariant ThingDiscovery::data(const QModelIndex &index, int role) const @@ -179,7 +179,7 @@ void ThingDiscovery::discoverThingsResponse(int commandId, const QVariantMap &pa QVariantList descriptors = params.value("thingDescriptors").toList(); foreach (const QVariant &descriptorVariant, descriptors) { if (!contains(descriptorVariant.toMap().value("id").toUuid())) { - beginInsertRows(QModelIndex(), m_foundThings.count(), m_foundThings.count()); + beginInsertRows(QModelIndex(), static_cast(m_foundThings.count()), static_cast(m_foundThings.count())); ThingDescriptor *descriptor = new ThingDescriptor(descriptorVariant.toMap().value("id").toUuid(), descriptorVariant.toMap().value("thingClassId").toUuid(), // Note: This will only be provided as of nymea 0.28! descriptorVariant.toMap().value("thingId").toUuid(), diff --git a/libnymea-app/things.cpp b/libnymea-app/things.cpp index b9c6afb3..fcbcf0c9 100644 --- a/libnymea-app/things.cpp +++ b/libnymea-app/things.cpp @@ -57,13 +57,13 @@ Thing *Things::getThing(const QUuid &thingId) const int Things::indexOf(Thing *thing) const { - return m_things.indexOf(thing); + return static_cast(static_cast(m_things.indexOf(thing))); } int Things::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_things.count(); + return static_cast(m_things.count()); } QVariant Things::data(const QModelIndex &index, int role) const @@ -105,23 +105,25 @@ void Things::addThings(const QList things) if (things.isEmpty()) { return; } - beginInsertRows(QModelIndex(), m_things.count(), m_things.count() + things.count() - 1); + const int insertStart = static_cast(m_things.count()); + const int insertEnd = insertStart + static_cast(things.count()) - 1; + beginInsertRows(QModelIndex(), insertStart, insertEnd); m_things.append(things); foreach (Thing *thing, things) { thing->setParent(this); connect(thing, &Thing::nameChanged, this, [thing, this]() { - int idx = m_things.indexOf(thing); + int idx = static_cast(m_things.indexOf(thing)); if (idx < 0) return; emit dataChanged(index(idx), index(idx), {RoleName}); }); connect(thing, &Thing::setupStatusChanged, this, [thing, this]() { - int idx = m_things.indexOf(thing); + int idx = static_cast(m_things.indexOf(thing)); if (idx < 0) return; emit dataChanged(index(idx), index(idx), {RoleSetupStatus, RoleSetupDisplayMessage}); }); connect(thing->states(), &States::dataChanged, this, [thing, this]() { - int idx = m_things.indexOf(thing); + int idx = static_cast(m_things.indexOf(thing)); if (idx < 0) return; emit dataChanged(index(idx), index(idx)); }); @@ -134,7 +136,7 @@ void Things::addThings(const QList things) void Things::removeThing(Thing *thing) { - int index = m_things.indexOf(thing); + int index = static_cast(m_things.indexOf(thing)); beginRemoveRows(QModelIndex(), index, index); qDebug() << "Removed thing" << thing->name(); m_things.takeAt(index)->deleteLater(); diff --git a/libnymea-app/types/actiontypes.cpp b/libnymea-app/types/actiontypes.cpp index 976a21b7..acfee3a8 100644 --- a/libnymea-app/types/actiontypes.cpp +++ b/libnymea-app/types/actiontypes.cpp @@ -53,7 +53,7 @@ ActionType *ActionTypes::getActionType(const QUuid &actionTypeId) const int ActionTypes::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_actionTypes.count(); + return static_cast(m_actionTypes.count()); } QVariant ActionTypes::data(const QModelIndex &index, int role) const @@ -73,7 +73,7 @@ QVariant ActionTypes::data(const QModelIndex &index, int role) const void ActionTypes::addActionType(ActionType *actionType) { actionType->setParent(this); - beginInsertRows(QModelIndex(), m_actionTypes.count(), m_actionTypes.count()); + beginInsertRows(QModelIndex(), static_cast(m_actionTypes.count()), static_cast(m_actionTypes.count())); //qDebug() << "ActionTypes: loaded actionType" << actionType->name(); m_actionTypes.append(actionType); endInsertRows(); diff --git a/libnymea-app/types/browseritems.cpp b/libnymea-app/types/browseritems.cpp index 814726c5..cd24a897 100644 --- a/libnymea-app/types/browseritems.cpp +++ b/libnymea-app/types/browseritems.cpp @@ -58,7 +58,7 @@ bool BrowserItems::busy() const int BrowserItems::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return m_list.count(); + return static_cast(m_list.count()); } QVariant BrowserItems::data(const QModelIndex &index, int role) const @@ -109,7 +109,7 @@ QHash BrowserItems::roleNames() const void BrowserItems::addBrowserItem(BrowserItem *browserItem) { browserItem->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(browserItem); endInsertRows(); emit countChanged(); @@ -117,7 +117,7 @@ void BrowserItems::addBrowserItem(BrowserItem *browserItem) void BrowserItems::removeItem(BrowserItem *browserItem) { - int idx = m_list.indexOf(browserItem); + int idx = static_cast(m_list.indexOf(browserItem)); if (idx < 0) { return; } diff --git a/libnymea-app/types/calendaritems.cpp b/libnymea-app/types/calendaritems.cpp index 4711fcfd..96de5acd 100644 --- a/libnymea-app/types/calendaritems.cpp +++ b/libnymea-app/types/calendaritems.cpp @@ -33,7 +33,7 @@ CalendarItems::CalendarItems(QObject *parent) : QAbstractListModel(parent) int CalendarItems::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant CalendarItems::data(const QModelIndex &index, int role) const @@ -46,7 +46,7 @@ QVariant CalendarItems::data(const QModelIndex &index, int role) const void CalendarItems::addCalendarItem(CalendarItem *calendarItem) { calendarItem->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(calendarItem); endInsertRows(); emit countChanged(); diff --git a/libnymea-app/types/eventdescriptors.cpp b/libnymea-app/types/eventdescriptors.cpp index 4d230e5c..091bb23d 100644 --- a/libnymea-app/types/eventdescriptors.cpp +++ b/libnymea-app/types/eventdescriptors.cpp @@ -36,7 +36,7 @@ EventDescriptors::EventDescriptors(QObject *parent) : int EventDescriptors::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant EventDescriptors::data(const QModelIndex &index, int role) const @@ -74,7 +74,7 @@ EventDescriptor *EventDescriptors::createNewEventDescriptor() void EventDescriptors::addEventDescriptor(EventDescriptor *eventDescriptor) { eventDescriptor->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(eventDescriptor); endInsertRows(); emit countChanged(); diff --git a/libnymea-app/types/eventtypes.cpp b/libnymea-app/types/eventtypes.cpp index 70b44314..54df6efc 100644 --- a/libnymea-app/types/eventtypes.cpp +++ b/libnymea-app/types/eventtypes.cpp @@ -54,7 +54,7 @@ EventType *EventTypes::getEventType(const QUuid &eventTypeId) const int EventTypes::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_eventTypes.count(); + return static_cast(m_eventTypes.count()); } QVariant EventTypes::data(const QModelIndex &index, int role) const @@ -74,7 +74,7 @@ QVariant EventTypes::data(const QModelIndex &index, int role) const void EventTypes::addEventType(EventType *eventType) { eventType->setParent(this); - beginInsertRows(QModelIndex(), m_eventTypes.count(), m_eventTypes.count()); + beginInsertRows(QModelIndex(), static_cast(m_eventTypes.count()), static_cast(m_eventTypes.count())); //qDebug() << "EventTypes: loaded eventType" << eventType->name(); m_eventTypes.append(eventType); endInsertRows(); diff --git a/libnymea-app/types/interfaces.cpp b/libnymea-app/types/interfaces.cpp index 9557c6e3..37b3ed5d 100644 --- a/libnymea-app/types/interfaces.cpp +++ b/libnymea-app/types/interfaces.cpp @@ -321,7 +321,7 @@ Interfaces::Interfaces(QObject *parent) : QAbstractListModel(parent) int Interfaces::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant Interfaces::data(const QModelIndex &index, int role) const diff --git a/libnymea-app/types/ioconnections.cpp b/libnymea-app/types/ioconnections.cpp index 112e3903..50069daf 100644 --- a/libnymea-app/types/ioconnections.cpp +++ b/libnymea-app/types/ioconnections.cpp @@ -32,7 +32,7 @@ IOConnections::IOConnections(QObject *parent) : QAbstractListModel(parent) int IOConnections::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant IOConnections::data(const QModelIndex &index, int role) const @@ -66,7 +66,7 @@ QHash IOConnections::roleNames() const void IOConnections::addIOConnection(IOConnection *ioConnection) { ioConnection->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(ioConnection); endInsertRows(); emit countChanged(); diff --git a/libnymea-app/types/networkdevices.cpp b/libnymea-app/types/networkdevices.cpp index c9e1fb97..fb08af28 100644 --- a/libnymea-app/types/networkdevices.cpp +++ b/libnymea-app/types/networkdevices.cpp @@ -33,7 +33,7 @@ NetworkDevices::NetworkDevices(QObject *parent): QAbstractListModel(parent) int NetworkDevices::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant NetworkDevices::data(const QModelIndex &index, int role) const @@ -70,14 +70,14 @@ QHash NetworkDevices::roleNames() const void NetworkDevices::addNetworkDevice(NetworkDevice *networkDevice) { networkDevice->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(networkDevice); connect(networkDevice, &NetworkDevice::bitRateChanged, this, [this, networkDevice](){ - emit dataChanged(index(m_list.indexOf(networkDevice)), index(m_list.indexOf(networkDevice)), {RoleBitRate}); + emit dataChanged(index(static_cast(m_list.indexOf(networkDevice))), index(static_cast(m_list.indexOf(networkDevice))), {RoleBitRate}); emit countChanged(); }); connect(networkDevice, &NetworkDevice::stateChanged, this, [this, networkDevice](){ - emit dataChanged(index(m_list.indexOf(networkDevice)), index(m_list.indexOf(networkDevice)), {RoleState}); + emit dataChanged(index(static_cast(m_list.indexOf(networkDevice))), index(static_cast(m_list.indexOf(networkDevice))), {RoleState}); emit countChanged(); }); endInsertRows(); @@ -149,7 +149,7 @@ void WiredNetworkDevices::addWiredNetworkDevice(WiredNetworkDevice *device) { NetworkDevices::addNetworkDevice(device); connect(device, &WiredNetworkDevice::pluggedInChanged, [this, device](){ - emit dataChanged(index(m_list.indexOf(device)), index(m_list.indexOf(device)), {RolePluggedIn}); + emit dataChanged(index(static_cast(m_list.indexOf(device))), index(static_cast(m_list.indexOf(device))), {RolePluggedIn}); emit countChanged(); }); } diff --git a/libnymea-app/types/packages.cpp b/libnymea-app/types/packages.cpp index 8a470b6e..8c63f2cc 100644 --- a/libnymea-app/types/packages.cpp +++ b/libnymea-app/types/packages.cpp @@ -33,7 +33,7 @@ Packages::Packages(QObject *parent) : QAbstractListModel(parent) int Packages::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant Packages::data(const QModelIndex &index, int role) const @@ -76,30 +76,30 @@ QHash Packages::roleNames() const void Packages::addPackage(Package *package) { package->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(package); connect(package, &Package::summaryChanged, this, [this, package](){ - emit dataChanged(index(m_list.indexOf(package)), index(m_list.indexOf(package)), {RoleSummary}); + emit dataChanged(index(static_cast(m_list.indexOf(package))), index(static_cast(m_list.indexOf(package))), {RoleSummary}); emit countChanged(); }); connect(package, &Package::installedVersionChanged, this, [this, package](){ - emit dataChanged(index(m_list.indexOf(package)), index(m_list.indexOf(package)), {RoleInstalledVersion}); + emit dataChanged(index(static_cast(m_list.indexOf(package))), index(static_cast(m_list.indexOf(package))), {RoleInstalledVersion}); emit countChanged(); }); connect(package, &Package::candidateVersionChanged, this, [this, package](){ - emit dataChanged(index(m_list.indexOf(package)), index(m_list.indexOf(package)), {RoleCandidateVersion}); + emit dataChanged(index(static_cast(m_list.indexOf(package))), index(static_cast(m_list.indexOf(package))), {RoleCandidateVersion}); emit countChanged(); }); connect(package, &Package::changelogChanged, this, [this, package](){ - emit dataChanged(index(m_list.indexOf(package)), index(m_list.indexOf(package)), {RoleChangelog}); + emit dataChanged(index(static_cast(m_list.indexOf(package))), index(static_cast(m_list.indexOf(package))), {RoleChangelog}); emit countChanged(); }); connect(package, &Package::updateAvailableChanged, this, [this, package](){ - emit dataChanged(index(m_list.indexOf(package)), index(m_list.indexOf(package)), {RoleUpdateAvailable}); + emit dataChanged(index(static_cast(m_list.indexOf(package))), index(static_cast(m_list.indexOf(package))), {RoleUpdateAvailable}); emit countChanged(); }); connect(package, &Package::rollbackAvailableChanged, this, [this, package](){ - emit dataChanged(index(m_list.indexOf(package)), index(m_list.indexOf(package)), {RoleRollbackAvailable}); + emit dataChanged(index(static_cast(m_list.indexOf(package))), index(static_cast(m_list.indexOf(package))), {RoleRollbackAvailable}); emit countChanged(); }); endInsertRows(); diff --git a/libnymea-app/types/paramdescriptors.cpp b/libnymea-app/types/paramdescriptors.cpp index b6791a3b..c42d1416 100644 --- a/libnymea-app/types/paramdescriptors.cpp +++ b/libnymea-app/types/paramdescriptors.cpp @@ -35,7 +35,7 @@ ParamDescriptors::ParamDescriptors(QObject *parent) : QAbstractListModel(parent) int ParamDescriptors::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant ParamDescriptors::data(const QModelIndex &index, int role) const @@ -76,7 +76,7 @@ ParamDescriptor *ParamDescriptors::createNewParamDescriptor() const void ParamDescriptors::addParamDescriptor(ParamDescriptor *paramDescriptor) { paramDescriptor->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(paramDescriptor); endInsertRows(); emit countChanged(); diff --git a/libnymea-app/types/params.cpp b/libnymea-app/types/params.cpp index 6a0f2be8..11c775e6 100644 --- a/libnymea-app/types/params.cpp +++ b/libnymea-app/types/params.cpp @@ -39,7 +39,7 @@ QList Params::params() int Params::count() const { - return m_params.count(); + return static_cast(m_params.count()); } Param *Params::get(int index) const @@ -62,13 +62,13 @@ Param *Params::getParam(const QUuid ¶mTypeId) const int Params::paramCount() const { - return m_params.count(); + return static_cast(m_params.count()); } int Params::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_params.count(); + return static_cast(m_params.count()); } QVariant Params::data(const QModelIndex &index, int role) const @@ -88,7 +88,7 @@ QVariant Params::data(const QModelIndex &index, int role) const void Params::addParam(Param *param) { param->setParent(this); - beginInsertRows(QModelIndex(), m_params.count(), m_params.count()); + beginInsertRows(QModelIndex(), static_cast(m_params.count()), static_cast(m_params.count())); //qDebug() << "Params: loaded param" << param->name(); m_params.append(param); endInsertRows(); diff --git a/libnymea-app/types/paramtypes.cpp b/libnymea-app/types/paramtypes.cpp index 1966eeab..3ac0016a 100644 --- a/libnymea-app/types/paramtypes.cpp +++ b/libnymea-app/types/paramtypes.cpp @@ -65,7 +65,7 @@ ParamType *ParamTypes::findByName(const QString &name) const int ParamTypes::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_paramTypes.count(); + return static_cast(m_paramTypes.count()); } QVariant ParamTypes::data(const QModelIndex &index, int role) const @@ -101,7 +101,7 @@ QVariant ParamTypes::data(const QModelIndex &index, int role) const void ParamTypes::addParamType(ParamType *paramType) { paramType->setParent(this); - beginInsertRows(QModelIndex(), m_paramTypes.count(), m_paramTypes.count()); + beginInsertRows(QModelIndex(), static_cast(m_paramTypes.count()), static_cast(m_paramTypes.count())); //qDebug() << "ParamTypes: loaded paramType" << paramType->name(); m_paramTypes.append(paramType); endInsertRows(); diff --git a/libnymea-app/types/plugins.cpp b/libnymea-app/types/plugins.cpp index 9bb2bb26..e7e776cf 100644 --- a/libnymea-app/types/plugins.cpp +++ b/libnymea-app/types/plugins.cpp @@ -39,7 +39,7 @@ QList Plugins::plugins() int Plugins::count() const { - return m_plugins.count(); + return static_cast(m_plugins.count()); } Plugin *Plugins::get(int index) const @@ -63,7 +63,7 @@ Plugin *Plugins::getPlugin(const QUuid &pluginId) const int Plugins::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_plugins.count(); + return static_cast(m_plugins.count()); } QVariant Plugins::data(const QModelIndex &index, int role) const @@ -82,7 +82,7 @@ QVariant Plugins::data(const QModelIndex &index, int role) const void Plugins::addPlugin(Plugin *plugin) { - beginInsertRows(QModelIndex(), m_plugins.count(), m_plugins.count()); + beginInsertRows(QModelIndex(), static_cast(m_plugins.count()), static_cast(m_plugins.count())); //qDebug() << "Plugin: loaded plugin" << plugin->name(); m_plugins.append(plugin); endInsertRows(); diff --git a/libnymea-app/types/repositories.cpp b/libnymea-app/types/repositories.cpp index 340c5963..3e466450 100644 --- a/libnymea-app/types/repositories.cpp +++ b/libnymea-app/types/repositories.cpp @@ -33,7 +33,7 @@ Repositories::Repositories(QObject *parent): QAbstractListModel(parent) int Repositories::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant Repositories::data(const QModelIndex &index, int role) const @@ -79,10 +79,10 @@ Repository *Repositories::getRepository(const QString &id) const void Repositories::addRepository(Repository *repository) { repository->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(repository); connect(repository, &Repository::enabledChanged, this, [this, repository](){ - QModelIndex idx = index(m_list.indexOf(repository)); + QModelIndex idx = index(static_cast(m_list.indexOf(repository))); emit dataChanged(idx, idx, {RoleEnabled}); }); endInsertRows(); diff --git a/libnymea-app/types/ruleactionparams.cpp b/libnymea-app/types/ruleactionparams.cpp index 9d68e48e..3d64f5a8 100644 --- a/libnymea-app/types/ruleactionparams.cpp +++ b/libnymea-app/types/ruleactionparams.cpp @@ -34,7 +34,7 @@ RuleActionParams::RuleActionParams(QObject *parent) : QAbstractListModel(parent) int RuleActionParams::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant RuleActionParams::data(const QModelIndex &index, int role) const @@ -65,7 +65,7 @@ QHash RuleActionParams::roleNames() const void RuleActionParams::addRuleActionParam(RuleActionParam *ruleActionParam) { ruleActionParam->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(ruleActionParam); endInsertRows(); emit countChanged(); diff --git a/libnymea-app/types/ruleactions.cpp b/libnymea-app/types/ruleactions.cpp index 04368442..d52c80d7 100644 --- a/libnymea-app/types/ruleactions.cpp +++ b/libnymea-app/types/ruleactions.cpp @@ -33,7 +33,7 @@ RuleActions::RuleActions(QObject *parent) : QAbstractListModel(parent) int RuleActions::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant RuleActions::data(const QModelIndex &index, int role) const @@ -46,7 +46,7 @@ QVariant RuleActions::data(const QModelIndex &index, int role) const void RuleActions::addRuleAction(RuleAction *ruleAction) { ruleAction->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(ruleAction); endInsertRows(); emit countChanged(); diff --git a/libnymea-app/types/rules.cpp b/libnymea-app/types/rules.cpp index c8a4b4d7..a993a1d5 100644 --- a/libnymea-app/types/rules.cpp +++ b/libnymea-app/types/rules.cpp @@ -44,7 +44,7 @@ void Rules::clear() int Rules::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant Rules::data(const QModelIndex &index, int role) const @@ -78,7 +78,7 @@ QHash Rules::roleNames() const void Rules::insert(Rule *rule) { rule->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(rule); connect(rule, &Rule::enabledChanged, this, &Rules::ruleChanged); connect(rule, &Rule::activeChanged, this, &Rules::ruleChanged); @@ -125,7 +125,7 @@ void Rules::ruleChanged() if (!rule) { return; } - int idx = m_list.indexOf(rule); + int idx = static_cast(m_list.indexOf(rule)); if (idx < 0) { qDebug() << "Rule not found in list. Discarding changed event."; return; diff --git a/libnymea-app/types/scripts.cpp b/libnymea-app/types/scripts.cpp index 6dcfcb13..58f57087 100644 --- a/libnymea-app/types/scripts.cpp +++ b/libnymea-app/types/scripts.cpp @@ -34,7 +34,7 @@ Scripts::Scripts(QObject *parent) : QAbstractListModel(parent) int Scripts::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant Scripts::data(const QModelIndex &index, int role) const @@ -69,13 +69,13 @@ void Scripts::clear() void Scripts::addScript(Script *script) { script->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(script); endInsertRows(); emit countChanged(); connect(script, &Script::nameChanged, this, [this, script](){ - int idx = m_list.indexOf(script); + int idx = static_cast(m_list.indexOf(script)); if (idx < 0) return; emit dataChanged(index(idx), index(idx), {RoleName}); }); diff --git a/libnymea-app/types/serialports.cpp b/libnymea-app/types/serialports.cpp index 5b8b4fd6..bfa9e936 100644 --- a/libnymea-app/types/serialports.cpp +++ b/libnymea-app/types/serialports.cpp @@ -32,7 +32,7 @@ SerialPorts::SerialPorts(QObject *parent) : QAbstractListModel(parent) int SerialPorts::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_serialPorts.count(); + return static_cast(m_serialPorts.count()); } QVariant SerialPorts::data(const QModelIndex &index, int role) const @@ -64,7 +64,7 @@ void SerialPorts::addSerialPort(SerialPort *serialPort) { serialPort->setParent(this); - beginInsertRows(QModelIndex(), m_serialPorts.count(), m_serialPorts.count()); + beginInsertRows(QModelIndex(), static_cast(m_serialPorts.count()), static_cast(m_serialPorts.count())); m_serialPorts.append(serialPort); endInsertRows(); diff --git a/libnymea-app/types/stateevaluators.cpp b/libnymea-app/types/stateevaluators.cpp index 2cc23272..a1bf6cb5 100644 --- a/libnymea-app/types/stateevaluators.cpp +++ b/libnymea-app/types/stateevaluators.cpp @@ -33,7 +33,7 @@ StateEvaluators::StateEvaluators(QObject *parent) : QAbstractListModel(parent) int StateEvaluators::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant StateEvaluators::data(const QModelIndex &index, int role) const @@ -52,7 +52,7 @@ QHash StateEvaluators::roleNames() const void StateEvaluators::addStateEvaluator(StateEvaluator *stateEvaluator) { stateEvaluator->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(stateEvaluator); endInsertRows(); emit countChanged(); diff --git a/libnymea-app/types/states.cpp b/libnymea-app/types/states.cpp index 7f53bbda..7f59b3e2 100644 --- a/libnymea-app/types/states.cpp +++ b/libnymea-app/types/states.cpp @@ -54,7 +54,7 @@ State *States::getState(const QUuid &stateTypeId) const int States::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_states.count(); + return static_cast(m_states.count()); } QVariant States::data(const QModelIndex &index, int role) const @@ -74,11 +74,11 @@ QVariant States::data(const QModelIndex &index, int role) const void States::addState(State *state) { state->setParent(this); - beginInsertRows(QModelIndex(), m_states.count(), m_states.count()); + beginInsertRows(QModelIndex(), static_cast(m_states.count()), static_cast(m_states.count())); //qDebug() << "States: loaded state" << state->stateTypeId(); m_states.append(state); connect(state, &State::valueChanged, this, [state, this]() { - int idx = m_states.indexOf(state); + int idx = static_cast(m_states.indexOf(state)); if (idx < 0) return; emit dataChanged(index(idx), index(idx), {ValueRole}); }); diff --git a/libnymea-app/types/statetype.cpp b/libnymea-app/types/statetype.cpp index 75be6eff..338c2c4b 100644 --- a/libnymea-app/types/statetype.cpp +++ b/libnymea-app/types/statetype.cpp @@ -113,7 +113,7 @@ QStringList StateType::possibleValuesDisplayNames() const QString StateType::localizedValue(const QVariant &value) const { - int idx = m_possibleValues.indexOf(value); + int idx = static_cast(m_possibleValues.indexOf(value)); return m_possibleValuesDisplayNames.at(idx); } diff --git a/libnymea-app/types/statetypes.cpp b/libnymea-app/types/statetypes.cpp index 8d440f6b..2b0a425f 100644 --- a/libnymea-app/types/statetypes.cpp +++ b/libnymea-app/types/statetypes.cpp @@ -57,7 +57,7 @@ StateType *StateTypes::getStateType(const QUuid &stateTypeId) const int StateTypes::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_stateTypes.count(); + return static_cast(m_stateTypes.count()); } QVariant StateTypes::data(const QModelIndex &index, int role) const @@ -88,7 +88,7 @@ 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()); + beginInsertRows(QModelIndex(), static_cast(m_stateTypes.count()), static_cast(m_stateTypes.count())); m_stateTypes.append(stateType); endInsertRows(); emit countChanged(); diff --git a/libnymea-app/types/tags.cpp b/libnymea-app/types/tags.cpp index bc7dc169..69b3f72d 100644 --- a/libnymea-app/types/tags.cpp +++ b/libnymea-app/types/tags.cpp @@ -39,7 +39,7 @@ Tags::Tags(QObject *parent) : QAbstractListModel(parent) int Tags::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant Tags::data(const QModelIndex &index, int role) const @@ -71,7 +71,7 @@ void Tags::addTag(Tag *tag) { tag->setParent(this); connect(tag, &Tag::valueChanged, this, &Tags::tagValueChanged); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(tag); endInsertRows(); qDebug() << "tags count changed"; @@ -83,7 +83,7 @@ void Tags::addTags(QList tags) if (tags.isEmpty()) { return; } - beginInsertRows(QModelIndex(), m_list.count(), m_list.count() + tags.count() - 1); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count()) + static_cast(tags.count()) - 1); foreach (Tag *tag, tags) { tag->setParent(this); connect(tag, &Tag::valueChanged, this, &Tags::tagValueChanged); @@ -95,7 +95,7 @@ void Tags::addTags(QList tags) void Tags::removeTag(Tag *tag) { - int idx = m_list.indexOf(tag); + int idx = static_cast(m_list.indexOf(tag)); if (idx < 0) { qWarning() << "Don't know this tag. Can't remove"; return; @@ -148,6 +148,6 @@ void Tags::tagValueChanged() { qCInfo(dcTags) << "Tag value in model changed"; Tag *tag = static_cast(sender()); - int idx = m_list.indexOf(tag); + int idx = static_cast(m_list.indexOf(tag)); emit dataChanged(index(idx, 0), index(idx, 0), {RoleValue}); } diff --git a/libnymea-app/types/timeeventitems.cpp b/libnymea-app/types/timeeventitems.cpp index af6c1cc7..9fab33c5 100644 --- a/libnymea-app/types/timeeventitems.cpp +++ b/libnymea-app/types/timeeventitems.cpp @@ -35,7 +35,7 @@ TimeEventItems::TimeEventItems(QObject *parent): int TimeEventItems::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant TimeEventItems::data(const QModelIndex &index, int role) const @@ -48,7 +48,7 @@ QVariant TimeEventItems::data(const QModelIndex &index, int role) const void TimeEventItems::addTimeEventItem(TimeEventItem *timeEventItem) { timeEventItem->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(timeEventItem); endInsertRows(); emit countChanged(); diff --git a/libnymea-app/types/tokeninfos.cpp b/libnymea-app/types/tokeninfos.cpp index 0bd2bdc8..29454a91 100644 --- a/libnymea-app/types/tokeninfos.cpp +++ b/libnymea-app/types/tokeninfos.cpp @@ -33,7 +33,7 @@ TokenInfos::TokenInfos(QObject *parent) : QAbstractListModel(parent) int TokenInfos::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant TokenInfos::data(const QModelIndex &index, int role) const @@ -64,7 +64,7 @@ QHash TokenInfos::roleNames() const void TokenInfos::addToken(TokenInfo *tokenInfo) { tokenInfo->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(tokenInfo); endInsertRows(); emit countChanged(); diff --git a/libnymea-app/types/vendors.cpp b/libnymea-app/types/vendors.cpp index dcbbdfc5..bb21f60d 100644 --- a/libnymea-app/types/vendors.cpp +++ b/libnymea-app/types/vendors.cpp @@ -34,7 +34,7 @@ Vendors::Vendors(QObject *parent) : int Vendors::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_vendors.count(); + return static_cast(m_vendors.count()); } QVariant Vendors::data(const QModelIndex &index, int role) const @@ -57,7 +57,7 @@ QVariant Vendors::data(const QModelIndex &index, int role) const void Vendors::addVendor(Vendor *vendor) { vendor->setParent(this); - beginInsertRows(QModelIndex(), m_vendors.count(), m_vendors.count()); + beginInsertRows(QModelIndex(), static_cast(m_vendors.count()), static_cast(m_vendors.count())); //qDebug() << "Vendors: loaded vendor" << vendor->name(); m_vendors.append(vendor); endInsertRows(); diff --git a/libnymea-app/types/wirelessaccesspoints.cpp b/libnymea-app/types/wirelessaccesspoints.cpp index 6bfa32c6..941f1772 100644 --- a/libnymea-app/types/wirelessaccesspoints.cpp +++ b/libnymea-app/types/wirelessaccesspoints.cpp @@ -54,7 +54,7 @@ void WirelessAccessPoints::setWirelessAccessPoints(QList int WirelessAccessPoints::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_wirelessAccessPoints.count(); + return static_cast(m_wirelessAccessPoints.count()); } QVariant WirelessAccessPoints::data(const QModelIndex &index, int role) const @@ -83,7 +83,7 @@ QVariant WirelessAccessPoints::data(const QModelIndex &index, int role) const int WirelessAccessPoints::count() const { - return m_wirelessAccessPoints.count(); + return static_cast(m_wirelessAccessPoints.count()); } WirelessAccessPoint *WirelessAccessPoints::getAccessPoint(const QString &ssid) const @@ -118,18 +118,18 @@ void WirelessAccessPoints::addWirelessAccessPoint(WirelessAccessPoint *accessPoi { accessPoint->setParent(this); - beginInsertRows(QModelIndex(), m_wirelessAccessPoints.count(), m_wirelessAccessPoints.count()); + beginInsertRows(QModelIndex(), static_cast(m_wirelessAccessPoints.count()), static_cast(m_wirelessAccessPoints.count())); qDebug() << "WirelessAccessPoints: access point added" << accessPoint->ssid() << accessPoint->macAddress(); m_wirelessAccessPoints.append(accessPoint); endInsertRows(); connect(accessPoint, &WirelessAccessPoint::signalStrengthChanged, this, [accessPoint, this]() { - int idx = m_wirelessAccessPoints.indexOf(accessPoint); + int idx = static_cast(m_wirelessAccessPoints.indexOf(accessPoint)); if (idx < 0) return; emit dataChanged(index(idx), index(idx), {WirelessAccesspointRoleSignalStrength}); }); connect(accessPoint, &WirelessAccessPoint::hostAddressChanged, this, [accessPoint, this]() { - int idx = m_wirelessAccessPoints.indexOf(accessPoint); + int idx = static_cast(m_wirelessAccessPoints.indexOf(accessPoint)); if (idx < 0) return; emit dataChanged(index(idx), index(idx), {WirelessAccesspointRoleHostAddress}); }); @@ -139,7 +139,7 @@ void WirelessAccessPoints::addWirelessAccessPoint(WirelessAccessPoint *accessPoi void WirelessAccessPoints::removeWirelessAccessPoint(WirelessAccessPoint *accessPoint) { - int index = m_wirelessAccessPoints.indexOf(accessPoint); + int index = static_cast(m_wirelessAccessPoints.indexOf(accessPoint)); beginRemoveRows(QModelIndex(), index, index); qDebug() << "WirelessAccessPoints: access point removed" << accessPoint->ssid() << accessPoint->macAddress(); m_wirelessAccessPoints.removeAt(index); diff --git a/libnymea-app/usermanager.cpp b/libnymea-app/usermanager.cpp index 1f56581b..9cd2a605 100644 --- a/libnymea-app/usermanager.cpp +++ b/libnymea-app/usermanager.cpp @@ -295,7 +295,7 @@ Users::Users(QObject *parent): QAbstractListModel(parent) int Users::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_users.count(); + return static_cast(m_users.count()); } QVariant Users::data(const QModelIndex &index, int role) const @@ -327,25 +327,25 @@ void Users::insertUser(UserInfo *userInfo) { userInfo->setParent(this); connect(userInfo, &UserInfo::displayNameChanged, this, [=](){ - int idx = m_users.indexOf(userInfo); + int idx = static_cast(m_users.indexOf(userInfo)); if (idx >= 0) { emit dataChanged(index(idx), index(idx), {RoleDisplayName}); } }); connect(userInfo, &UserInfo::emailChanged, this, [=](){ - int idx = m_users.indexOf(userInfo); + int idx = static_cast(m_users.indexOf(userInfo)); if (idx >= 0) { emit dataChanged(index(idx), index(idx), {RoleEmail}); } }); connect(userInfo, &UserInfo::scopesChanged, this, [=](){ - int idx = m_users.indexOf(userInfo); + int idx = static_cast(m_users.indexOf(userInfo)); if (idx >= 0) { emit dataChanged(index(idx), index(idx), {RoleScopes}); } }); - beginInsertRows(QModelIndex(), m_users.count(), m_users.count()); + beginInsertRows(QModelIndex(), static_cast(m_users.count()), static_cast(m_users.count())); m_users.append(userInfo); endInsertRows(); emit countChanged(); diff --git a/libnymea-app/wifisetup/bluetoothdeviceinfos.cpp b/libnymea-app/wifisetup/bluetoothdeviceinfos.cpp index 021df6a0..262f5ad7 100644 --- a/libnymea-app/wifisetup/bluetoothdeviceinfos.cpp +++ b/libnymea-app/wifisetup/bluetoothdeviceinfos.cpp @@ -40,7 +40,7 @@ QList BluetoothDeviceInfos::deviceInfos() int BluetoothDeviceInfos::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_deviceInfos.count(); + return static_cast(m_deviceInfos.count()); } QVariant BluetoothDeviceInfos::data(const QModelIndex &index, int role) const @@ -64,7 +64,7 @@ QVariant BluetoothDeviceInfos::data(const QModelIndex &index, int role) const int BluetoothDeviceInfos::count() const { - return m_deviceInfos.count(); + return static_cast(m_deviceInfos.count()); } BluetoothDeviceInfo *BluetoothDeviceInfos::get(int index) const @@ -79,10 +79,10 @@ void BluetoothDeviceInfos::addBluetoothDeviceInfo(BluetoothDeviceInfo *deviceInf { qDebug() << "Adding device" << deviceInfo->name(); deviceInfo->setParent(this); - beginInsertRows(QModelIndex(), m_deviceInfos.count(), m_deviceInfos.count()); + beginInsertRows(QModelIndex(), static_cast(m_deviceInfos.count()), static_cast(m_deviceInfos.count())); m_deviceInfos.append(deviceInfo); connect(deviceInfo, &BluetoothDeviceInfo::deviceChanged, this, [=]{ - int idx = m_deviceInfos.indexOf(deviceInfo); + int idx = static_cast(m_deviceInfos.indexOf(deviceInfo)); QModelIndex index = this->index(idx); emit dataChanged(index, index); }); diff --git a/libnymea-app/zigbee/zigbeeadapters.cpp b/libnymea-app/zigbee/zigbeeadapters.cpp index d69dca23..0012b86a 100644 --- a/libnymea-app/zigbee/zigbeeadapters.cpp +++ b/libnymea-app/zigbee/zigbeeadapters.cpp @@ -32,7 +32,7 @@ ZigbeeAdapters::ZigbeeAdapters(QObject *parent) : QAbstractListModel(parent) int ZigbeeAdapters::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_adapters.count(); + return static_cast(m_adapters.count()); } QVariant ZigbeeAdapters::data(const QModelIndex &index, int role) const @@ -70,36 +70,36 @@ void ZigbeeAdapters::addAdapter(ZigbeeAdapter *adapter) { adapter->setParent(this); - beginInsertRows(QModelIndex(), m_adapters.count(), m_adapters.count()); + beginInsertRows(QModelIndex(), static_cast(m_adapters.count()), static_cast(m_adapters.count())); m_adapters.append(adapter); connect(adapter, &ZigbeeAdapter::nameChanged, this, [this, adapter]() { - QModelIndex idx = index(m_adapters.indexOf(adapter), 0); + QModelIndex idx = index(static_cast(m_adapters.indexOf(adapter)), 0); emit dataChanged(idx, idx, {RoleName}); }); connect(adapter, &ZigbeeAdapter::descriptionChanged, this, [this, adapter]() { - QModelIndex idx = index(m_adapters.indexOf(adapter), 0); + QModelIndex idx = index(static_cast(m_adapters.indexOf(adapter)), 0); emit dataChanged(idx, idx, {RoleDescription}); }); connect(adapter, &ZigbeeAdapter::serialPortChanged, this, [this, adapter]() { - QModelIndex idx = index(m_adapters.indexOf(adapter), 0); + QModelIndex idx = index(static_cast(m_adapters.indexOf(adapter)), 0); emit dataChanged(idx, idx, {RoleSerialPort}); }); connect(adapter, &ZigbeeAdapter::hardwareRecognizedChanged, this, [this, adapter]() { - QModelIndex idx = index(m_adapters.indexOf(adapter), 0); + QModelIndex idx = index(static_cast(m_adapters.indexOf(adapter)), 0); emit dataChanged(idx, idx, {RoleHardwareRecognized}); }); connect(adapter, &ZigbeeAdapter::backendChanged, this, [this, adapter]() { - QModelIndex idx = index(m_adapters.indexOf(adapter), 0); + QModelIndex idx = index(static_cast(m_adapters.indexOf(adapter)), 0); emit dataChanged(idx, idx, {RoleBackend}); }); connect(adapter, &ZigbeeAdapter::baudRateChanged, this, [this, adapter]() { - QModelIndex idx = index(m_adapters.indexOf(adapter), 0); + QModelIndex idx = index(static_cast(m_adapters.indexOf(adapter)), 0); emit dataChanged(idx, idx, {RoleBaudRate}); }); diff --git a/libnymea-app/zigbee/zigbeenetworks.cpp b/libnymea-app/zigbee/zigbeenetworks.cpp index 3bc8d00a..86bb23d9 100644 --- a/libnymea-app/zigbee/zigbeenetworks.cpp +++ b/libnymea-app/zigbee/zigbeenetworks.cpp @@ -32,7 +32,7 @@ ZigbeeNetworks::ZigbeeNetworks(QObject *parent) : QAbstractListModel(parent) int ZigbeeNetworks::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_networks.count(); + return static_cast(m_networks.count()); } QVariant ZigbeeNetworks::data(const QModelIndex &index, int role) const @@ -91,70 +91,70 @@ QHash ZigbeeNetworks::roleNames() const void ZigbeeNetworks::addNetwork(ZigbeeNetwork *network) { network->setParent(this); - beginInsertRows(QModelIndex(), m_networks.count(), m_networks.count()); + beginInsertRows(QModelIndex(), static_cast(m_networks.count()), static_cast(m_networks.count())); m_networks.append(network); connect(network, &ZigbeeNetwork::networkUuidChanged, this, [this, network]() { - QModelIndex idx = index(m_networks.indexOf(network), 0); + QModelIndex idx = index(static_cast(m_networks.indexOf(network)), 0); emit dataChanged(idx, idx, {RoleUuid}); }); connect(network, &ZigbeeNetwork::serialPortChanged, this, [this, network]() { - QModelIndex idx = index(m_networks.indexOf(network), 0); + QModelIndex idx = index(static_cast(m_networks.indexOf(network)), 0); emit dataChanged(idx, idx, {RoleSerialPort}); }); connect(network, &ZigbeeNetwork::baudRateChanged, this, [this, network]() { - QModelIndex idx = index(m_networks.indexOf(network), 0); + QModelIndex idx = index(static_cast(m_networks.indexOf(network)), 0); emit dataChanged(idx, idx, {RoleBaudRate}); }); connect(network, &ZigbeeNetwork::macAddressChanged, this, [this, network]() { - QModelIndex idx = index(m_networks.indexOf(network), 0); + QModelIndex idx = index(static_cast(m_networks.indexOf(network)), 0); emit dataChanged(idx, idx, {RoleMacAddress}); }); connect(network, &ZigbeeNetwork::firmwareVersionChanged, this, [this, network]() { - QModelIndex idx = index(m_networks.indexOf(network), 0); + QModelIndex idx = index(static_cast(m_networks.indexOf(network)), 0); emit dataChanged(idx, idx, {RoleFirmwareVersion}); }); connect(network, &ZigbeeNetwork::panIdChanged, this, [this, network]() { - QModelIndex idx = index(m_networks.indexOf(network), 0); + QModelIndex idx = index(static_cast(m_networks.indexOf(network)), 0); emit dataChanged(idx, idx, {RolePanId}); }); connect(network, &ZigbeeNetwork::channelChanged, this, [this, network]() { - QModelIndex idx = index(m_networks.indexOf(network), 0); + QModelIndex idx = index(static_cast(m_networks.indexOf(network)), 0); emit dataChanged(idx, idx, {RoleChannel}); }); connect(network, &ZigbeeNetwork::channelMaskChanged, this, [this, network]() { - QModelIndex idx = index(m_networks.indexOf(network), 0); + QModelIndex idx = index(static_cast(m_networks.indexOf(network)), 0); emit dataChanged(idx, idx, {RoleChannelMask}); }); connect(network, &ZigbeeNetwork::permitJoiningEnabledChanged, this, [this, network]() { - QModelIndex idx = index(m_networks.indexOf(network), 0); + QModelIndex idx = index(static_cast(m_networks.indexOf(network)), 0); emit dataChanged(idx, idx, {RolePermitJoiningEnabled}); }); connect(network, &ZigbeeNetwork::permitJoiningDurationChanged, this, [this, network]() { - QModelIndex idx = index(m_networks.indexOf(network), 0); + QModelIndex idx = index(static_cast(m_networks.indexOf(network)), 0); emit dataChanged(idx, idx, {RolePermitJoiningDuration}); }); connect(network, &ZigbeeNetwork::permitJoiningRemainingChanged, this, [this, network]() { - QModelIndex idx = index(m_networks.indexOf(network), 0); + QModelIndex idx = index(static_cast(m_networks.indexOf(network)), 0); emit dataChanged(idx, idx, {RolePermitJoiningRemaining}); }); connect(network, &ZigbeeNetwork::backendChanged, this, [this, network]() { - QModelIndex idx = index(m_networks.indexOf(network), 0); + QModelIndex idx = index(static_cast(m_networks.indexOf(network)), 0); emit dataChanged(idx, idx, {RoleBackend}); }); connect(network, &ZigbeeNetwork::networkStateChanged, this, [this, network]() { - QModelIndex idx = index(m_networks.indexOf(network), 0); + QModelIndex idx = index(static_cast(m_networks.indexOf(network)), 0); emit dataChanged(idx, idx, {RoleNetworkState}); }); diff --git a/libnymea-app/zigbee/zigbeenodes.cpp b/libnymea-app/zigbee/zigbeenodes.cpp index 63f81fd1..c7f91c87 100644 --- a/libnymea-app/zigbee/zigbeenodes.cpp +++ b/libnymea-app/zigbee/zigbeenodes.cpp @@ -32,7 +32,7 @@ ZigbeeNodes::ZigbeeNodes(QObject *parent) : QAbstractListModel(parent) int ZigbeeNodes::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_nodes.count(); + return static_cast(m_nodes.count()); } QVariant ZigbeeNodes::data(const QModelIndex &index, int role) const @@ -88,56 +88,56 @@ QHash ZigbeeNodes::roleNames() const void ZigbeeNodes::addNode(ZigbeeNode *node) { node->setParent(this); - beginInsertRows(QModelIndex(), m_nodes.count(), m_nodes.count()); + beginInsertRows(QModelIndex(), static_cast(m_nodes.count()), static_cast(m_nodes.count())); m_nodes.append(node); connect(node, &ZigbeeNode::networkAddressChanged, this, [this, node]() { - QModelIndex idx = index(m_nodes.indexOf(node), 0); + QModelIndex idx = index(static_cast(m_nodes.indexOf(node)), 0); emit dataChanged(idx, idx, {RoleNetworkAddress}); }); connect(node, &ZigbeeNode::typeChanged, this, [this, node]() { - QModelIndex idx = index(m_nodes.indexOf(node), 0); + QModelIndex idx = index(static_cast(m_nodes.indexOf(node)), 0); emit dataChanged(idx, idx, {RoleType}); }); connect(node, &ZigbeeNode::stateChanged, this, [this, node]() { - QModelIndex idx = index(m_nodes.indexOf(node), 0); + QModelIndex idx = index(static_cast(m_nodes.indexOf(node)), 0); emit dataChanged(idx, idx, {RoleState}); }); connect(node, &ZigbeeNode::manufacturerChanged, this, [this, node]() { - QModelIndex idx = index(m_nodes.indexOf(node), 0); + QModelIndex idx = index(static_cast(m_nodes.indexOf(node)), 0); emit dataChanged(idx, idx, {RoleManufacturer}); }); connect(node, &ZigbeeNode::modelChanged, this, [this, node]() { - QModelIndex idx = index(m_nodes.indexOf(node), 0); + QModelIndex idx = index(static_cast(m_nodes.indexOf(node)), 0); emit dataChanged(idx, idx, {RoleModel}); }); connect(node, &ZigbeeNode::versionChanged, this, [this, node]() { - QModelIndex idx = index(m_nodes.indexOf(node), 0); + QModelIndex idx = index(static_cast(m_nodes.indexOf(node)), 0); emit dataChanged(idx, idx, {RoleVersion}); }); connect(node, &ZigbeeNode::rxOnWhenIdleChanged, this, [this, node]() { - QModelIndex idx = index(m_nodes.indexOf(node), 0); + QModelIndex idx = index(static_cast(m_nodes.indexOf(node)), 0); emit dataChanged(idx, idx, {RoleRxOnWhenIdle}); }); connect(node, &ZigbeeNode::reachableChanged, this, [this, node]() { - QModelIndex idx = index(m_nodes.indexOf(node), 0); + QModelIndex idx = index(static_cast(m_nodes.indexOf(node)), 0); emit dataChanged(idx, idx, {RoleReachable}); }); connect(node, &ZigbeeNode::lqiChanged, this, [this, node]() { - QModelIndex idx = index(m_nodes.indexOf(node), 0); + QModelIndex idx = index(static_cast(m_nodes.indexOf(node)), 0); emit dataChanged(idx, idx, {RoleLqi}); }); connect(node, &ZigbeeNode::lastSeenChanged, this, [this, node]() { - QModelIndex idx = index(m_nodes.indexOf(node), 0); + QModelIndex idx = index(static_cast(m_nodes.indexOf(node)), 0); emit dataChanged(idx, idx, {RoleLastSeen}); }); diff --git a/libnymea-app/zwave/zwavenetwork.cpp b/libnymea-app/zwave/zwavenetwork.cpp index 3fbdb8b7..5fc949b1 100644 --- a/libnymea-app/zwave/zwavenetwork.cpp +++ b/libnymea-app/zwave/zwavenetwork.cpp @@ -172,7 +172,7 @@ ZWaveNetworks::ZWaveNetworks(QObject *parent): int ZWaveNetworks::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant ZWaveNetworks::data(const QModelIndex &index, int role) const @@ -219,13 +219,13 @@ void ZWaveNetworks::clear() void ZWaveNetworks::addNetwork(ZWaveNetwork *network) { network->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(network); endInsertRows(); emit countChanged(); connect(network, &ZWaveNetwork::networkStateChanged, this, [this, network](){ - QModelIndex idx = index(m_list.indexOf(network)); + QModelIndex idx = index(static_cast(m_list.indexOf(network))); emit dataChanged(idx, idx, {RoleNetworkState}); }); } diff --git a/libnymea-app/zwave/zwavenode.cpp b/libnymea-app/zwave/zwavenode.cpp index abff9941..091bac30 100644 --- a/libnymea-app/zwave/zwavenode.cpp +++ b/libnymea-app/zwave/zwavenode.cpp @@ -316,7 +316,7 @@ ZWaveNodes::ZWaveNodes(QObject *parent): int ZWaveNodes::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant ZWaveNodes::data(const QModelIndex &index, int role) const @@ -342,7 +342,7 @@ void ZWaveNodes::clear() void ZWaveNodes::addNode(ZWaveNode *node) { node->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + beginInsertRows(QModelIndex(), static_cast(m_list.count()), static_cast(m_list.count())); m_list.append(node); endInsertRows(); emit countChanged(); diff --git a/nymea-app/configuredhostsmodel.cpp b/nymea-app/configuredhostsmodel.cpp index 843e5be6..7c44d67c 100644 --- a/nymea-app/configuredhostsmodel.cpp +++ b/nymea-app/configuredhostsmodel.cpp @@ -55,14 +55,14 @@ ConfiguredHostsModel::ConfiguredHostsModel(QObject *parent) : QAbstractListModel // Make sure the currentIndex from the config isn't out of place if (m_currentIndex >= m_list.count()) { - m_currentIndex = m_list.count()-1; + m_currentIndex = static_cast(m_list.count()) - 1; } } int ConfiguredHostsModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant ConfiguredHostsModel::data(const QModelIndex &index, int role) const @@ -180,7 +180,7 @@ void ConfiguredHostsModel::removeHost(int index) } if (m_currentIndex >= m_list.count()) { - m_currentIndex = m_list.count() - 1; + m_currentIndex = static_cast(m_list.count()) - 1; emit currentIndexChanged(); } } @@ -201,13 +201,14 @@ void ConfiguredHostsModel::move(int from, int to) int ConfiguredHostsModel::indexOf(ConfiguredHost *host) const { - return m_list.indexOf(host); + return static_cast(static_cast(m_list.indexOf(host))); } void ConfiguredHostsModel::addHost(ConfiguredHost *host) { host->setParent(this); - beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + const int insertPos = static_cast(m_list.count()); + beginInsertRows(QModelIndex(), insertPos, insertPos); connect(host->engine()->jsonRpcClient(), &JsonRpcClient::currentHostChanged, this, [=]{ if (host->engine()->jsonRpcClient()->currentHost()) { host->setUuid(host->engine()->jsonRpcClient()->currentHost()->uuid()); @@ -222,7 +223,7 @@ void ConfiguredHostsModel::addHost(ConfiguredHost *host) saveToDisk(); }); connect(host, &ConfiguredHost::nameChanged, this, [=](){ - QModelIndex idx = index(m_list.indexOf(host)); + QModelIndex idx = index(static_cast(static_cast(m_list.indexOf(host)))); emit dataChanged(idx, idx, {RoleName}); }); connect(host, &ConfiguredHost::uuidChanged, this, [=](){ diff --git a/nymea-app/dashboard/dashboardmodel.cpp b/nymea-app/dashboard/dashboardmodel.cpp index 61587542..3c65d739 100644 --- a/nymea-app/dashboard/dashboardmodel.cpp +++ b/nymea-app/dashboard/dashboardmodel.cpp @@ -36,7 +36,7 @@ DashboardModel::DashboardModel(QObject *parent) : QAbstractListModel(parent) int DashboardModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_list.count(); + return static_cast(m_list.count()); } QVariant DashboardModel::data(const QModelIndex &index, int role) const @@ -64,7 +64,7 @@ QHash DashboardModel::roleNames() const DashboardItem *DashboardModel::get(int index) const { - if (index < 0 || index >= m_list.count()) { + if (index < 0 || index >= m_list.size()) { return nullptr; } return m_list.at(index); @@ -246,17 +246,17 @@ QByteArray DashboardModel::toJson() const void DashboardModel::addItem(DashboardItem *item, int index) { - if (index < 0 || index > m_list.count()) { - index = m_list.count(); + if (index < 0 || index > m_list.size()) { + index = static_cast(m_list.size()); } connect(item, &DashboardItem::rowSpanChanged, this, [this, item](){ - int idx = m_list.indexOf(item); + int idx = static_cast(static_cast(m_list.indexOf(item))); if (idx >= 0) { emit dataChanged(this->index(idx), this->index(idx), {RoleRowSpan}); } }); connect(item, &DashboardItem::columnSpanChanged, this, [this, item](){ - int idx = m_list.indexOf(item); + int idx = static_cast(static_cast(m_list.indexOf(item))); if (idx >= 0) { emit dataChanged(this->index(idx), this->index(idx), {RoleColumnSpan}); } diff --git a/nymea-app/main.cpp b/nymea-app/main.cpp index bd0ff131..a1059530 100644 --- a/nymea-app/main.cpp +++ b/nymea-app/main.cpp @@ -38,6 +38,8 @@ #include #include #include +#include +#include #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #include @@ -246,5 +248,16 @@ int main(int argc, char *argv[]) engine->load(QUrl(QLatin1String("qrc:/ui/Nymea.qml"))); +#ifdef Q_OS_IOS + if (!engine->rootObjects().isEmpty()) { + if (QWindow *window = qobject_cast(engine->rootObjects().constFirst())) { + const QRect screenRect = window->screen()->availableGeometry(); + window->setPosition(screenRect.topLeft()); + window->resize(screenRect.size()); + window->showFullScreen(); + } + } +#endif + return application.exec(); } diff --git a/nymea-app/nfcthingactionwriter.cpp b/nymea-app/nfcthingactionwriter.cpp index 6634965e..8afbf1c3 100644 --- a/nymea-app/nfcthingactionwriter.cpp +++ b/nymea-app/nfcthingactionwriter.cpp @@ -103,7 +103,7 @@ RuleActions *NfcThingActionWriter::actions() const int NfcThingActionWriter::messageSize() const { - return m_currentMessage.toByteArray().size(); + return static_cast(m_currentMessage.toByteArray().size()); } NfcThingActionWriter::TagStatus NfcThingActionWriter::status() const @@ -212,4 +212,3 @@ void NfcThingActionWriter::targetLost(QNearFieldTarget *target) m_status = TagStatusWaiting; emit statusChanged(); } - diff --git a/nymea-app/nymea-app.pro b/nymea-app/nymea-app.pro index ffb97878..9ef24745 100644 --- a/nymea-app/nymea-app.pro +++ b/nymea-app/nymea-app.pro @@ -165,9 +165,13 @@ ios: { OTHER_FILES += $${OBJECTIVE_SOURCES} LIBS += -framework CoreLocation \ + -framework CoreBluetooth \ + -framework CoreNFC + # Add Firebase SDK QMAKE_LFLAGS += -ObjC $(inherited) + DEFINES += FIREBASE_ANALYTICS_SUPPRESS_WARNING firebase_files.files += $$files($${IOS_PACKAGE_DIR}/GoogleService-Info.plist) QMAKE_BUNDLE_DATA += firebase_files INCLUDEPATH += ../3rdParty/ios/ @@ -182,6 +186,13 @@ ios: { -framework "PromisesObjC" \ + LIBS += -L$$top_builddir/libnymea-app -lnymea-app \ + -L$$top_builddir/experiences/airconditioning -lnymea-app-airconditioning \ + + PRE_TARGETDEPS += $$top_builddir/libnymea-app/libnymea-app.a \ + $$top_builddir/experiences/airconditioning/libnymea-app-airconditioning.a + + # Configure generated xcode project to have our bundle id QMAKE_TARGET_BUNDLE_PREFIX=$${IOS_BUNDLE_PREFIX} QMAKE_BUNDLE=$${IOS_BUNDLE_NAME} @@ -235,4 +246,3 @@ target.path = /usr/bin INSTALLS += target DISTFILES += - diff --git a/nymea-app/platformhelper.cpp b/nymea-app/platformhelper.cpp index 241f1c88..74ba475c 100644 --- a/nymea-app/platformhelper.cpp +++ b/nymea-app/platformhelper.cpp @@ -187,22 +187,22 @@ void PlatformHelper::setBottomPanelColor(const QColor &color) int PlatformHelper::topPadding() const { - return 0; + return m_topPadding; } int PlatformHelper::bottomPadding() const { - return 0; + return m_bottomPadding; } int PlatformHelper::leftPadding() const { - return 0; + return m_leftPadding; } int PlatformHelper::rightPadding() const { - return 0; + return m_rightPadding; } bool PlatformHelper::darkModeEnabled() const @@ -239,6 +239,32 @@ void PlatformHelper::vibrate(PlatformHelper::HapticsFeedback feedbackType) Q_UNUSED(feedbackType) } +void PlatformHelper::setSafeAreaPadding(int top, int right, int bottom, int left) +{ + bool changed = false; + if (m_topPadding != top) { + m_topPadding = top; + changed = true; + emit topPaddingChanged(); + } + if (m_rightPadding != right) { + m_rightPadding = right; + changed = true; + emit rightPaddingChanged(); + } + if (m_bottomPadding != bottom) { + m_bottomPadding = bottom; + changed = true; + emit bottomPaddingChanged(); + } + if (m_leftPadding != left) { + m_leftPadding = left; + changed = true; + emit leftPaddingChanged(); + } + Q_UNUSED(changed) +} + void PlatformHelper::toClipBoard(const QString &text) { QApplication::clipboard()->setText(text); diff --git a/nymea-app/platformhelper.h b/nymea-app/platformhelper.h index 0626c41e..30c9aa99 100644 --- a/nymea-app/platformhelper.h +++ b/nymea-app/platformhelper.h @@ -52,10 +52,10 @@ class PlatformHelper : public QObject Q_PROPERTY(bool darkModeEnabled READ darkModeEnabled NOTIFY darkModeEnabledChanged) Q_PROPERTY(QVariantList pendingNotificationActions READ pendingNotificationActions NOTIFY pendingNotificationActionsChanged) Q_PROPERTY(bool locationServicesEnabled READ locationServicesEnabled NOTIFY locationServicesEnabledChanged) - Q_PROPERTY(int topPadding READ topPadding CONSTANT) - Q_PROPERTY(int bottomPadding READ bottomPadding CONSTANT) - Q_PROPERTY(int leftPadding READ leftPadding CONSTANT) - Q_PROPERTY(int rightPadding READ rightPadding CONSTANT) + Q_PROPERTY(int topPadding READ topPadding NOTIFY topPaddingChanged) + Q_PROPERTY(int bottomPadding READ bottomPadding NOTIFY bottomPaddingChanged) + Q_PROPERTY(int leftPadding READ leftPadding NOTIFY leftPaddingChanged) + Q_PROPERTY(int rightPadding READ rightPadding NOTIFY rightPaddingChanged) public: enum HapticsFeedback { @@ -123,9 +123,14 @@ signals: void splashVisibleChanged(); void pendingNotificationActionsChanged(); void locationServicesEnabledChanged(); + void topPaddingChanged(); + void bottomPaddingChanged(); + void leftPaddingChanged(); + void rightPaddingChanged(); protected: explicit PlatformHelper(QObject *parent = nullptr); + void setSafeAreaPadding(int top, int right, int bottom, int left); private: static PlatformHelper *s_instance; @@ -136,6 +141,11 @@ private: bool m_splashVisible = true; QHash m_pendingNotificationActions; + + int m_topPadding = 0; + int m_bottomPadding = 0; + int m_leftPadding = 0; + int m_rightPadding = 0; }; #endif // PLATFORMHELPER_H diff --git a/nymea-app/platformintegration/ios/platformhelperios.cpp b/nymea-app/platformintegration/ios/platformhelperios.cpp index 3990ec2a..abbd28b0 100644 --- a/nymea-app/platformintegration/ios/platformhelperios.cpp +++ b/nymea-app/platformintegration/ios/platformhelperios.cpp @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include PlatformHelperIOS::PlatformHelperIOS(QObject *parent) : PlatformHelper(parent) @@ -34,10 +36,22 @@ PlatformHelperIOS::PlatformHelperIOS(QObject *parent) : PlatformHelper(parent) QtWebView::initialize(); QScreen *screen = qApp->primaryScreen(); - screen->setOrientationUpdateMask(Qt::PortraitOrientation | Qt::LandscapeOrientation | Qt::InvertedPortraitOrientation | Qt::InvertedLandscapeOrientation); + //screen->setOrientationUpdateMask(Qt::PortraitOrientation | Qt::LandscapeOrientation | Qt::InvertedPortraitOrientation | Qt::InvertedLandscapeOrientation); QObject::connect(screen, &QScreen::orientationChanged, qApp, [this](Qt::ScreenOrientation) { - setBottomPanelColor(bottomPanelColor()); + applyPanelColors(); }); + QObject::connect(screen, &QScreen::availableGeometryChanged, qApp, [this](const QRect &) { + applyPanelColors(); + }); + QObject::connect(qApp, &QGuiApplication::focusWindowChanged, this, [this](QWindow *) { + QTimer::singleShot(0, this, &PlatformHelperIOS::applyPanelColors); + }); + QObject::connect(qApp, &QGuiApplication::applicationStateChanged, this, [this](Qt::ApplicationState state) { + if (state == Qt::ApplicationActive) { + QTimer::singleShot(0, this, &PlatformHelperIOS::applyPanelColors); + } + }); + QTimer::singleShot(0, this, &PlatformHelperIOS::applyPanelColors); } void PlatformHelperIOS::hideSplashScreen() @@ -115,3 +129,9 @@ void PlatformHelperIOS::setBottomPanelColor(const QColor &color) } +void PlatformHelperIOS::applyPanelColors() +{ + setTopPanelColor(topPanelColor()); + setBottomPanelColor(bottomPanelColor()); + updateSafeAreaPadding(); +} diff --git a/nymea-app/platformintegration/ios/platformhelperios.h b/nymea-app/platformintegration/ios/platformhelperios.h index 70e23ddd..2591d96a 100644 --- a/nymea-app/platformintegration/ios/platformhelperios.h +++ b/nymea-app/platformintegration/ios/platformhelperios.h @@ -63,6 +63,9 @@ private: void generateSelectionFeedback(); void generateImpactFeedback(); void generateNotificationFeedback(); + + void applyPanelColors(); + void updateSafeAreaPadding(); }; #endif // PLATFORMHELPERIOS_H diff --git a/nymea-app/platformintegration/ios/platformhelperios.mm b/nymea-app/platformintegration/ios/platformhelperios.mm index da12a6f6..a418c6f2 100644 --- a/nymea-app/platformintegration/ios/platformhelperios.mm +++ b/nymea-app/platformintegration/ios/platformhelperios.mm @@ -4,8 +4,47 @@ #import #include +#include #include "platformintegration/ios/platformhelperios.h" +static UIWindow *activeWindow() +{ + UIApplication *application = [UIApplication sharedApplication]; + UIWindow *window = application.keyWindow; + if (window) { + return window; + } + + for (UIWindow *candidate in application.windows) { + if (candidate.isKeyWindow) { + return candidate; + } + } + + return application.windows.firstObject; +} + +static CGRect statusBarFrameForWindow(UIWindow *window) +{ + if (!window) { + return CGRectZero; + } + + if (@available(iOS 13.0, *)) { + UIStatusBarManager *statusBarManager = window.windowScene.statusBarManager; + if (statusBarManager) { + CGRect frame = statusBarManager.statusBarFrame; + if (!CGRectIsEmpty(frame)) { + return frame; + } + } + CGFloat height = window.safeAreaInsets.top; + return CGRectMake(0, 0, window.bounds.size.width, height); + } + + return [UIApplication sharedApplication].statusBarFrame; +} + QString PlatformHelperIOS::readKeyChainEntry(const QString &service, const QString &key) { NSDictionary *const query = @{ @@ -28,7 +67,7 @@ QString PlatformHelperIOS::readKeyChainEntry(const QString &service, const QStri } if (dataRef) - [dataRef release]; + CFRelease(dataRef); // SecItemCopyMatching creates a retained object; release with CFRelease. return data; } @@ -101,19 +140,28 @@ void PlatformHelperIOS::generateNotificationFeedback() void PlatformHelperIOS::setTopPanelColorInternal(const QColor &color) { - if (@available(iOS 13.0, *)) { - UIView *statusBar = [[UIView alloc]initWithFrame:[UIApplication sharedApplication].keyWindow.windowScene.statusBarManager.statusBarFrame]; - if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]) { - statusBar.backgroundColor = [UIColor colorWithRed:color.redF() green:color.greenF() blue:color.blueF() alpha:color.alphaF()]; - } - [[UIApplication sharedApplication].keyWindow addSubview:statusBar]; - } else { - UIView *statusBar = [[UIView alloc]initWithFrame:[UIApplication sharedApplication].keyWindow.frame]; - if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]) { - statusBar.backgroundColor = [UIColor colorWithRed:color.redF() green:color.greenF() blue:color.blueF() alpha:color.alphaF()]; - } + UIWindow *window = activeWindow(); + if (!window) { + return; } + static const NSInteger statusBarViewTag = 0x6E796D; // "nym" to avoid clashes + UIColor *uiColor = [UIColor colorWithRed:color.redF() green:color.greenF() blue:color.blueF() alpha:color.alphaF()]; + CGRect frame = statusBarFrameForWindow(window); + UIView *statusBar = [window viewWithTag:statusBarViewTag]; + if (statusBar) { + statusBar.frame = frame; + } else { + statusBar = [[UIView alloc] initWithFrame:frame]; + statusBar.tag = statusBarViewTag; + statusBar.autoresizingMask = UIViewAutoresizingFlexibleWidth; + [window addSubview:statusBar]; + } + if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]) { + statusBar.backgroundColor = uiColor; + } + [window bringSubviewToFront:statusBar]; + if (((color.red() * 299 + color.green() * 587 + color.blue() * 114) / 1000) > 123) { [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDarkContent animated:YES]; } else { @@ -124,8 +172,16 @@ void PlatformHelperIOS::setTopPanelColorInternal(const QColor &color) void PlatformHelperIOS::setBottomPanelColorInternal(const QColor &color) { //Bottom - UIApplication *app = [UIApplication sharedApplication]; - app.windows.firstObject.backgroundColor = [UIColor colorWithRed:color.redF() green:color.greenF() blue:color.blueF() alpha:color.alphaF()]; + UIColor *uiColor = [UIColor colorWithRed:color.redF() green:color.greenF() blue:color.blueF() alpha:color.alphaF()]; + UIWindow *window = activeWindow(); + if (!window) { + return; + } + + window.backgroundColor = uiColor; + if (window.rootViewController && window.rootViewController.view) { + window.rootViewController.view.backgroundColor = uiColor; + } } bool PlatformHelperIOS::darkModeEnabled() const @@ -143,4 +199,17 @@ void PlatformHelperIOS::shareFile(const QString &fileName) [qtController presentViewController:activityController animated:YES completion:nil]; } - +void PlatformHelperIOS::updateSafeAreaPadding() +{ + UIWindow *window = activeWindow(); + UIEdgeInsets insets = UIEdgeInsetsZero; + if (window) { + if (@available(iOS 11.0, *)) { + insets = window.safeAreaInsets; + } else { + CGRect statusFrame = statusBarFrameForWindow(window); + insets.top = statusFrame.size.height; + } + } + setSafeAreaPadding(qRound(insets.top), qRound(insets.right), qRound(insets.bottom), qRound(insets.left)); +} diff --git a/nymea-app/platformintegration/ios/platformpermissionsios.cpp b/nymea-app/platformintegration/ios/platformpermissionsios.cpp index bd3cb609..755c93d6 100644 --- a/nymea-app/platformintegration/ios/platformpermissionsios.cpp +++ b/nymea-app/platformintegration/ios/platformpermissionsios.cpp @@ -68,6 +68,8 @@ PlatformPermissions::PermissionStatus PlatformPermissionsIOS::checkPermission(Pe void PlatformPermissionsIOS::requestPermission(Permission permission) { switch (permission) { + case PermissionNone: + break; case PermissionLocalNetwork: requestLocalNetworkPermission(); break; diff --git a/nymea-app/platformintegration/ios/platformpermissionsios.mm b/nymea-app/platformintegration/ios/platformpermissionsios.mm index 4896bf6e..55129169 100644 --- a/nymea-app/platformintegration/ios/platformpermissionsios.mm +++ b/nymea-app/platformintegration/ios/platformpermissionsios.mm @@ -61,7 +61,7 @@ void PlatformPermissionsIOS::requestNotificationPermission() { UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter]; [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionBadge + UNAuthorizationOptionSound) - completionHandler:^(BOOL granted, NSError * _Nullable error) { + completionHandler:^(BOOL granted, NSError * _Nullable) { m_notificationPermissions = granted ? PermissionStatusGranted : PermissionStatusDenied; emit notificationsPermissionChanged(); }]; diff --git a/nymea-app/ui/Nymea.qml b/nymea-app/ui/Nymea.qml index 4b777c5d..49b80522 100644 --- a/nymea-app/ui/Nymea.qml +++ b/nymea-app/ui/Nymea.qml @@ -36,8 +36,8 @@ import NymeaApp.Utils ApplicationWindow { id: app visible: true - width: 360 - height: 580 + width: Qt.platform.os === "ios" ? Screen.width : 360 + height: Qt.platform.os === "ios" ? Screen.height : 580 minimumWidth: 350 minimumHeight: 480 visibility: kioskMode ? ApplicationWindow.FullScreen : settings.viewMode From c7cb2d794b95a6e1fbed3e88b2f2314113bef2c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 25 Nov 2025 12:56:53 +0100 Subject: [PATCH 07/50] Use deleteLater() in model cleanups in order to prevent QML evaluation errors --- experiences/airconditioning/temperatureschedule.cpp | 4 +++- experiences/airconditioning/temperatureschedule.h | 2 +- libnymea-app/configuration/mqttpolicies.cpp | 4 +++- libnymea-app/configuration/serverconfigurations.cpp | 4 +++- libnymea-app/energy/energylogs.cpp | 4 +++- libnymea-app/modbus/modbusrtumasters.cpp | 4 +++- libnymea-app/models/logsmodel.cpp | 4 +++- libnymea-app/models/logsmodelng.cpp | 4 +++- libnymea-app/models/newlogsmodel.cpp | 8 ++++++-- libnymea-app/serverdebug/serverloggingcategories.cpp | 7 +++++-- libnymea-app/thingclasses.cpp | 4 +++- libnymea-app/things.cpp | 5 +++-- libnymea-app/types/ioconnections.cpp | 4 +++- libnymea-app/types/networkdevices.cpp | 4 +++- libnymea-app/types/packages.cpp | 4 +++- libnymea-app/types/packages.h | 2 +- libnymea-app/types/paramdescriptors.cpp | 4 +++- libnymea-app/types/plugins.cpp | 4 +++- libnymea-app/types/repositories.cpp | 4 +++- libnymea-app/types/ruleactionparams.cpp | 4 +++- libnymea-app/types/rules.cpp | 4 +++- libnymea-app/types/scripts.cpp | 4 +++- libnymea-app/types/serialports.cpp | 4 +++- libnymea-app/types/statetypes.cpp | 4 +++- libnymea-app/types/tags.cpp | 4 +++- libnymea-app/types/vendors.cpp | 4 +++- libnymea-app/types/wirelessaccesspoints.cpp | 8 ++++++-- libnymea-app/wifisetup/bluetoothdeviceinfos.cpp | 4 +++- libnymea-app/zigbee/zigbeeadapters.cpp | 4 +++- libnymea-app/zigbee/zigbeenetworks.cpp | 4 +++- libnymea-app/zigbee/zigbeenodes.cpp | 4 +++- libnymea-app/zwave/zwavenetwork.cpp | 6 +++++- libnymea-app/zwave/zwavenode.cpp | 5 ++++- nymea-app/dashboard/dashboardmodel.cpp | 4 +++- 34 files changed, 109 insertions(+), 38 deletions(-) diff --git a/experiences/airconditioning/temperatureschedule.cpp b/experiences/airconditioning/temperatureschedule.cpp index be04888b..6808598e 100644 --- a/experiences/airconditioning/temperatureschedule.cpp +++ b/experiences/airconditioning/temperatureschedule.cpp @@ -123,7 +123,9 @@ QHash TemperatureDaySchedule::roleNames() const void TemperatureDaySchedule::clear() { beginResetModel(); - qDeleteAll(m_list); + foreach (TemperatureSchedule *schedule, m_list) + schedule->deleteLater(); + m_list.clear(); endResetModel(); } diff --git a/experiences/airconditioning/temperatureschedule.h b/experiences/airconditioning/temperatureschedule.h index bef2e7d1..673d80fa 100644 --- a/experiences/airconditioning/temperatureschedule.h +++ b/experiences/airconditioning/temperatureschedule.h @@ -90,7 +90,7 @@ signals: void countChanged(); private: - QList m_list; + QList m_list; }; class TemperatureWeekSchedule: public QAbstractListModel diff --git a/libnymea-app/configuration/mqttpolicies.cpp b/libnymea-app/configuration/mqttpolicies.cpp index 5faf8c37..fe8a9d65 100644 --- a/libnymea-app/configuration/mqttpolicies.cpp +++ b/libnymea-app/configuration/mqttpolicies.cpp @@ -127,7 +127,9 @@ MqttPolicy *MqttPolicies::get(int index) const void MqttPolicies::clear() { beginResetModel(); - qDeleteAll(m_list); + foreach (MqttPolicy* policy, m_list) + policy->deleteLater(); + m_list.clear(); endResetModel(); } diff --git a/libnymea-app/configuration/serverconfigurations.cpp b/libnymea-app/configuration/serverconfigurations.cpp index cb7ba2af..a084ed19 100644 --- a/libnymea-app/configuration/serverconfigurations.cpp +++ b/libnymea-app/configuration/serverconfigurations.cpp @@ -107,7 +107,9 @@ void ServerConfigurations::removeConfiguration(const QString &id) void ServerConfigurations::clear() { beginResetModel(); - qDeleteAll(m_list); + foreach (ServerConfiguration *config, m_list) + config->deleteLater(); + m_list.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/energy/energylogs.cpp b/libnymea-app/energy/energylogs.cpp index 12d6de36..745ae0a7 100644 --- a/libnymea-app/energy/energylogs.cpp +++ b/libnymea-app/energy/energylogs.cpp @@ -422,7 +422,9 @@ void EnergyLogs::clear() { int count = static_cast(m_list.count()); beginResetModel(); - qDeleteAll(m_list); + foreach (EnergyLogEntry *entry, m_list) + entry->deleteLater(); + m_list.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/modbus/modbusrtumasters.cpp b/libnymea-app/modbus/modbusrtumasters.cpp index b30154ff..a1755836 100644 --- a/libnymea-app/modbus/modbusrtumasters.cpp +++ b/libnymea-app/modbus/modbusrtumasters.cpp @@ -156,7 +156,9 @@ void ModbusRtuMasters::removeModbusRtuMaster(const QUuid &modbusUuid) void ModbusRtuMasters::clear() { beginResetModel(); - qDeleteAll(m_modbusRtuMasters); + foreach (ModbusRtuMaster *master, m_modbusRtuMasters) + master->deleteLater(); + m_modbusRtuMasters.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/models/logsmodel.cpp b/libnymea-app/models/logsmodel.cpp index dcdfa5e6..f02b037f 100644 --- a/libnymea-app/models/logsmodel.cpp +++ b/libnymea-app/models/logsmodel.cpp @@ -150,7 +150,9 @@ void LogsModel::setTypeIds(const QStringList &typeIds) emit typeIdsChanged(); qCDebug(dcLogEngine()) << "Resetting model because type ids changed"; beginResetModel(); - qDeleteAll(m_list); + foreach (LogEntry *entry, m_list) + entry->deleteLater(); + m_list.clear(); m_generatedEntries = 0; endResetModel(); diff --git a/libnymea-app/models/logsmodelng.cpp b/libnymea-app/models/logsmodelng.cpp index 30e454fd..42ef3f04 100644 --- a/libnymea-app/models/logsmodelng.cpp +++ b/libnymea-app/models/logsmodelng.cpp @@ -161,7 +161,9 @@ void LogsModelNg::setTypeIds(const QStringList &typeIds) m_typeIds = fixedTypeIds; emit typeIdsChanged(); beginResetModel(); - qDeleteAll(m_list); + foreach (LogEntry *entry, m_list) + entry->deleteLater(); + m_list.clear(); endResetModel(); fetchMore(); diff --git a/libnymea-app/models/newlogsmodel.cpp b/libnymea-app/models/newlogsmodel.cpp index 17733488..2e051631 100644 --- a/libnymea-app/models/newlogsmodel.cpp +++ b/libnymea-app/models/newlogsmodel.cpp @@ -358,7 +358,9 @@ void NewLogsModel::clear() { int count = static_cast(m_list.count()); beginResetModel(); - qDeleteAll(m_list); + foreach (NewLogEntry *entry, m_list) + entry->deleteLater(); + m_list.clear(); m_currentNewest = QDateTime(); m_lastOffset = 0; @@ -447,7 +449,9 @@ void NewLogsModel::logsReply(int commandId, const QVariantMap &data) m_list.clear(); endResetModel(); emit entriesRemoved(0, oldEntries.count()); - qDeleteAll(oldEntries); + + foreach (NewLogEntry *entry, oldEntries) + entry->deleteLater(); if (!entries.isEmpty()) { beginInsertRows(QModelIndex(), 0, static_cast(entries.count()) - 1); diff --git a/libnymea-app/serverdebug/serverloggingcategories.cpp b/libnymea-app/serverdebug/serverloggingcategories.cpp index 1731124c..28246dac 100644 --- a/libnymea-app/serverdebug/serverloggingcategories.cpp +++ b/libnymea-app/serverdebug/serverloggingcategories.cpp @@ -60,8 +60,11 @@ void ServerLoggingCategories::createFromVariantList(const QVariantList &loggingC { beginResetModel(); - if (!m_list.isEmpty()) - qDeleteAll(m_list); + if (!m_list.isEmpty()) { + foreach (ServerLoggingCategory *category, m_list) { + category->deleteLater(); + } + } foreach(const QVariant &categoryVariant, loggingCategories) { QVariantMap categoryMap = categoryVariant.toMap(); diff --git a/libnymea-app/thingclasses.cpp b/libnymea-app/thingclasses.cpp index 4aa37abf..fac066a6 100644 --- a/libnymea-app/thingclasses.cpp +++ b/libnymea-app/thingclasses.cpp @@ -102,7 +102,9 @@ void ThingClasses::addThingClass(ThingClass *thingClass) void ThingClasses::clearModel() { beginResetModel(); - qDeleteAll(m_thingClasses); + foreach (ThingClass *thingClass, m_thingClasses) + thingClass->deleteLater(); + m_thingClasses.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/things.cpp b/libnymea-app/things.cpp index fcbcf0c9..7c4f1474 100644 --- a/libnymea-app/things.cpp +++ b/libnymea-app/things.cpp @@ -23,7 +23,6 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "things.h" -#include "engine.h" #include @@ -148,7 +147,9 @@ void Things::removeThing(Thing *thing) void Things::clearModel() { beginResetModel(); - qDeleteAll(m_things); + foreach (Thing *thing, m_things) + thing->deleteLater(); + m_things.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/types/ioconnections.cpp b/libnymea-app/types/ioconnections.cpp index 50069daf..f6881cdf 100644 --- a/libnymea-app/types/ioconnections.cpp +++ b/libnymea-app/types/ioconnections.cpp @@ -90,7 +90,9 @@ void IOConnections::removeIOConnection(const QUuid &ioConnectionId) void IOConnections::clearModel() { beginResetModel(); - qDeleteAll(m_list); + foreach (IOConnection *connection, m_list) + connection->deleteLater(); + m_list.clear(); endResetModel(); } diff --git a/libnymea-app/types/networkdevices.cpp b/libnymea-app/types/networkdevices.cpp index fb08af28..a8a5cc12 100644 --- a/libnymea-app/types/networkdevices.cpp +++ b/libnymea-app/types/networkdevices.cpp @@ -124,7 +124,9 @@ NetworkDevice *NetworkDevices::getNetworkDevice(const QString &interface) void NetworkDevices::clear() { beginResetModel(); - qDeleteAll(m_list); + foreach (NetworkDevice *device, m_list) + device->deleteLater(); + m_list.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/types/packages.cpp b/libnymea-app/types/packages.cpp index 8c63f2cc..3639d52f 100644 --- a/libnymea-app/types/packages.cpp +++ b/libnymea-app/types/packages.cpp @@ -146,7 +146,9 @@ Package *Packages::getPackage(const QString &packageId) void Packages::clear() { beginResetModel(); - qDeleteAll(m_list); + foreach (Package *package, m_list) + package->deleteLater(); + m_list.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/types/packages.h b/libnymea-app/types/packages.h index 02b4e481..e6108e6a 100644 --- a/libnymea-app/types/packages.h +++ b/libnymea-app/types/packages.h @@ -64,7 +64,7 @@ signals: void countChanged(); private: - QList m_list; + QList m_list; }; #endif // PACKAGES_H diff --git a/libnymea-app/types/paramdescriptors.cpp b/libnymea-app/types/paramdescriptors.cpp index c42d1416..1e5d9ffd 100644 --- a/libnymea-app/types/paramdescriptors.cpp +++ b/libnymea-app/types/paramdescriptors.cpp @@ -119,7 +119,9 @@ void ParamDescriptors::setParamDescriptorByName(const QString ¶mName, const void ParamDescriptors::clear() { beginResetModel(); - qDeleteAll(m_list); + foreach (ParamDescriptor *descriptor, m_list) + descriptor->deleteLater(); + m_list.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/types/plugins.cpp b/libnymea-app/types/plugins.cpp index e7e776cf..d371d9a7 100644 --- a/libnymea-app/types/plugins.cpp +++ b/libnymea-app/types/plugins.cpp @@ -91,7 +91,9 @@ void Plugins::addPlugin(Plugin *plugin) void Plugins::clearModel() { beginResetModel(); - qDeleteAll(m_plugins); + foreach (Plugin *plugin, m_plugins) + plugin->deleteLater(); + m_plugins.clear(); endResetModel(); } diff --git a/libnymea-app/types/repositories.cpp b/libnymea-app/types/repositories.cpp index 3e466450..56495302 100644 --- a/libnymea-app/types/repositories.cpp +++ b/libnymea-app/types/repositories.cpp @@ -111,7 +111,9 @@ void Repositories::removeRepository(const QString &repositoryId) void Repositories::clear() { beginResetModel(); - qDeleteAll(m_list); + foreach (Repository *repo, m_list) + repo->deleteLater(); + m_list.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/types/ruleactionparams.cpp b/libnymea-app/types/ruleactionparams.cpp index 3d64f5a8..ee372217 100644 --- a/libnymea-app/types/ruleactionparams.cpp +++ b/libnymea-app/types/ruleactionparams.cpp @@ -198,7 +198,9 @@ bool RuleActionParams::hasRuleActionParam(const QUuid ¶mTypeId) const void RuleActionParams::clear() { beginResetModel(); - qDeleteAll(m_list); + foreach (RuleActionParam *param, m_list) + param->deleteLater(); + m_list.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/types/rules.cpp b/libnymea-app/types/rules.cpp index a993a1d5..f6ee83ad 100644 --- a/libnymea-app/types/rules.cpp +++ b/libnymea-app/types/rules.cpp @@ -35,7 +35,9 @@ Rules::Rules(QObject *parent) : QAbstractListModel(parent) void Rules::clear() { beginResetModel(); - qDeleteAll(m_list); + foreach (Rule *rule, m_list) + rule->deleteLater(); + m_list.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/types/scripts.cpp b/libnymea-app/types/scripts.cpp index 58f57087..a2a57263 100644 --- a/libnymea-app/types/scripts.cpp +++ b/libnymea-app/types/scripts.cpp @@ -60,7 +60,9 @@ QHash Scripts::roleNames() const void Scripts::clear() { beginResetModel(); - qDeleteAll(m_list); + foreach (Script *script, m_list) + script->deleteLater(); + m_list.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/types/serialports.cpp b/libnymea-app/types/serialports.cpp index bfa9e936..6ea334ff 100644 --- a/libnymea-app/types/serialports.cpp +++ b/libnymea-app/types/serialports.cpp @@ -87,7 +87,9 @@ void SerialPorts::removeSerialPort(const QString &systemLocation) void SerialPorts::clear() { beginResetModel(); - qDeleteAll(m_serialPorts); + foreach (SerialPort *port, m_serialPorts) + port->deleteLater(); + m_serialPorts.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/types/statetypes.cpp b/libnymea-app/types/statetypes.cpp index 2b0a425f..1ade70b0 100644 --- a/libnymea-app/types/statetypes.cpp +++ b/libnymea-app/types/statetypes.cpp @@ -118,7 +118,9 @@ QList StateTypes::ioStateTypes(Types::IOType ioType) const void StateTypes::clearModel() { beginResetModel(); - qDeleteAll(m_stateTypes); + foreach (StateType *stateType, m_stateTypes) + stateType->deleteLater(); + m_stateTypes.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/types/tags.cpp b/libnymea-app/types/tags.cpp index 69b3f72d..e4e6dfb2 100644 --- a/libnymea-app/types/tags.cpp +++ b/libnymea-app/types/tags.cpp @@ -138,7 +138,9 @@ Tag *Tags::findRuleTag(const QUuid &ruleId, const QString &tagId) const void Tags::clear() { beginResetModel(); - qDeleteAll(m_list); + foreach (Tag *tag, m_list) + tag->deleteLater(); + m_list.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/types/vendors.cpp b/libnymea-app/types/vendors.cpp index bb21f60d..56dbac1d 100644 --- a/libnymea-app/types/vendors.cpp +++ b/libnymea-app/types/vendors.cpp @@ -67,7 +67,9 @@ void Vendors::addVendor(Vendor *vendor) void Vendors::clearModel() { beginResetModel(); - qDeleteAll(m_vendors); + foreach (Vendor *vendor, m_vendors) + vendor->deleteLater(); + m_vendors.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/types/wirelessaccesspoints.cpp b/libnymea-app/types/wirelessaccesspoints.cpp index 941f1772..9d2d5292 100644 --- a/libnymea-app/types/wirelessaccesspoints.cpp +++ b/libnymea-app/types/wirelessaccesspoints.cpp @@ -42,7 +42,9 @@ void WirelessAccessPoints::setWirelessAccessPoints(QList beginResetModel(); // Delete all - qDeleteAll(m_wirelessAccessPoints); + foreach (WirelessAccessPoint *ap, m_wirelessAccessPoints) + ap->deleteLater(); + m_wirelessAccessPoints.clear(); m_wirelessAccessPoints = wirelessAccessPoints; @@ -108,7 +110,9 @@ WirelessAccessPoint *WirelessAccessPoints::get(int index) void WirelessAccessPoints::clearModel() { beginResetModel(); - qDeleteAll(m_wirelessAccessPoints); + foreach (WirelessAccessPoint *ap, m_wirelessAccessPoints) + ap->deleteLater(); + m_wirelessAccessPoints.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/wifisetup/bluetoothdeviceinfos.cpp b/libnymea-app/wifisetup/bluetoothdeviceinfos.cpp index 262f5ad7..8af9f00e 100644 --- a/libnymea-app/wifisetup/bluetoothdeviceinfos.cpp +++ b/libnymea-app/wifisetup/bluetoothdeviceinfos.cpp @@ -93,7 +93,9 @@ void BluetoothDeviceInfos::addBluetoothDeviceInfo(BluetoothDeviceInfo *deviceInf void BluetoothDeviceInfos::clearModel() { beginResetModel(); - qDeleteAll(m_deviceInfos); + foreach (BluetoothDeviceInfo *deviceInfo, m_deviceInfos) + deviceInfo->deleteLater(); + m_deviceInfos.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/zigbee/zigbeeadapters.cpp b/libnymea-app/zigbee/zigbeeadapters.cpp index 0012b86a..0f895768 100644 --- a/libnymea-app/zigbee/zigbeeadapters.cpp +++ b/libnymea-app/zigbee/zigbeeadapters.cpp @@ -123,7 +123,9 @@ void ZigbeeAdapters::removeAdapter(const QString &serialPort) void ZigbeeAdapters::clear() { beginResetModel(); - qDeleteAll(m_adapters); + foreach (ZigbeeAdapter *adapter, m_adapters) + adapter->deleteLater(); + m_adapters.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/zigbee/zigbeenetworks.cpp b/libnymea-app/zigbee/zigbeenetworks.cpp index 86bb23d9..f00cc03d 100644 --- a/libnymea-app/zigbee/zigbeenetworks.cpp +++ b/libnymea-app/zigbee/zigbeenetworks.cpp @@ -179,7 +179,9 @@ void ZigbeeNetworks::removeNetwork(const QUuid &networkUuid) void ZigbeeNetworks::clear() { beginResetModel(); - qDeleteAll(m_networks); + foreach (ZigbeeNetwork *network, m_networks) + network->deleteLater(); + m_networks.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/zigbee/zigbeenodes.cpp b/libnymea-app/zigbee/zigbeenodes.cpp index c7f91c87..cbf42760 100644 --- a/libnymea-app/zigbee/zigbeenodes.cpp +++ b/libnymea-app/zigbee/zigbeenodes.cpp @@ -164,7 +164,9 @@ void ZigbeeNodes::removeNode(const QString &ieeeAddress) void ZigbeeNodes::clear() { beginResetModel(); - qDeleteAll(m_nodes); + foreach (ZigbeeNode *node, m_nodes) + node->deleteLater(); + m_nodes.clear(); endResetModel(); emit countChanged(); diff --git a/libnymea-app/zwave/zwavenetwork.cpp b/libnymea-app/zwave/zwavenetwork.cpp index 5fc949b1..86d11b83 100644 --- a/libnymea-app/zwave/zwavenetwork.cpp +++ b/libnymea-app/zwave/zwavenetwork.cpp @@ -212,8 +212,12 @@ QHash ZWaveNetworks::roleNames() const void ZWaveNetworks::clear() { beginResetModel(); - qDeleteAll(m_list); + foreach (ZWaveNetwork *network, m_list) + network->deleteLater(); + + m_list.clear(); endResetModel(); + emit countChanged(); } void ZWaveNetworks::addNetwork(ZWaveNetwork *network) diff --git a/libnymea-app/zwave/zwavenode.cpp b/libnymea-app/zwave/zwavenode.cpp index 091bac30..394a2ce7 100644 --- a/libnymea-app/zwave/zwavenode.cpp +++ b/libnymea-app/zwave/zwavenode.cpp @@ -334,7 +334,10 @@ QHash ZWaveNodes::roleNames() const void ZWaveNodes::clear() { beginResetModel(); - qDeleteAll(m_list); + foreach (ZWaveNode *node, m_list) + node->deleteLater(); + + m_list.clear(); endResetModel(); emit countChanged(); } diff --git a/nymea-app/dashboard/dashboardmodel.cpp b/nymea-app/dashboard/dashboardmodel.cpp index 3c65d739..5ecd0fe2 100644 --- a/nymea-app/dashboard/dashboardmodel.cpp +++ b/nymea-app/dashboard/dashboardmodel.cpp @@ -151,7 +151,9 @@ void DashboardModel::loadFromJson(const QByteArray &json) } beginResetModel(); - qDeleteAll(m_list); + foreach (DashboardItem *item, m_list) + item->deleteLater(); + m_list.clear(); QJsonDocument jsonDoc = QJsonDocument::fromJson(json); From c5797ffc444b56522a337787e0ce43ede515797d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 25 Nov 2025 14:29:15 +0100 Subject: [PATCH 08/50] Update QtZeroConf and fix Android builds --- QtZeroConf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QtZeroConf b/QtZeroConf index 6e70786e..a6c8302b 160000 --- a/QtZeroConf +++ b/QtZeroConf @@ -1 +1 @@ -Subproject commit 6e70786eef77303b5d630ce4acc7c49e03a58992 +Subproject commit a6c8302b3accf6be2ecb7c40ec69d1707a2c5765 From 8736717370c397ff5dc5323799d7d4bafb2647fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 25 Nov 2025 15:41:15 +0100 Subject: [PATCH 09/50] Android: Make Edge To Edge work again for SDK >= 35 --- .../android/platformhelperandroid.cpp | 49 +++++++++++++------ .../android/platformhelperandroid.h | 3 ++ 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/nymea-app/platformintegration/android/platformhelperandroid.cpp b/nymea-app/platformintegration/android/platformhelperandroid.cpp index 3ad8a7e3..a0455e2d 100644 --- a/nymea-app/platformintegration/android/platformhelperandroid.cpp +++ b/nymea-app/platformintegration/android/platformhelperandroid.cpp @@ -29,6 +29,7 @@ #include #include #include +#include // WindowManager.LayoutParams #define FLAG_TRANSLUCENT_STATUS 0x04000000 @@ -89,8 +90,20 @@ PlatformHelperAndroid::PlatformHelperAndroid(QObject *parent) : PlatformHelper(p qCritical() << "----> Application state changed" << state; if (state == Qt::ApplicationActive) { emit locationServicesEnabledChanged(); + updateSafeAreaPadding(); } }); + + if (QScreen *screen = qApp->primaryScreen()) { + connect(screen, &QScreen::orientationChanged, this, [this](Qt::ScreenOrientation){ + updateSafeAreaPadding(); + }); + connect(screen, &QScreen::availableGeometryChanged, this, [this](const QRect &){ + updateSafeAreaPadding(); + }); + } + + QTimer::singleShot(0, this, &PlatformHelperAndroid::updateSafeAreaPadding); } void PlatformHelperAndroid::hideSplashScreen() @@ -266,26 +279,34 @@ void PlatformHelperAndroid::setBottomPanelTheme(Theme theme) // }); } +void PlatformHelperAndroid::updateSafeAreaPadding() +{ + int topPaddingPx = 0; + int bottomPaddingPx = 0; + + QJniObject context = QNativeInterface::QAndroidApplication::context(); + if (context.isValid()) { + topPaddingPx = context.callMethod("topPadding", "()I"); + bottomPaddingPx = context.callMethod("bottomPadding", "()I"); + } + + QScreen *screen = qApp->primaryScreen(); + qreal dpr = screen ? screen->devicePixelRatio() : 1.0; + if (dpr <= 0.0) { + dpr = 1.0; + } + + setSafeAreaPadding(qRound(topPaddingPx / dpr), 0, qRound(bottomPaddingPx / dpr), 0); +} + int PlatformHelperAndroid::topPadding() const { - // Edge to edge has been forced since android SDK 35 - // We don't want to handle it in earlied versions. - // if (QtAndroid::androidSdkVersion() < 35) - // return 0; - - //return QNativeInterface::QAndroidApplication::context().callMethod("topPadding") / QApplication::primaryScreen()->devicePixelRatio(); - return 0; + return PlatformHelper::topPadding(); } int PlatformHelperAndroid::bottomPadding() const { - // Edge to edge has been forced since android SDK 35 - // We don't want to handle it in earlied versions. - // if (QtAndroid::androidSdkVersion() < 35) - // return 0; - - // return QNativeInterface::QAndroidApplication::context().callMethod("bottomPadding") / QApplication::primaryScreen()->devicePixelRatio(); - return 0; + return PlatformHelper::bottomPadding(); } bool PlatformHelperAndroid::darkModeEnabled() const diff --git a/nymea-app/platformintegration/android/platformhelperandroid.h b/nymea-app/platformintegration/android/platformhelperandroid.h index 3edbaeda..bb60badd 100644 --- a/nymea-app/platformintegration/android/platformhelperandroid.h +++ b/nymea-app/platformintegration/android/platformhelperandroid.h @@ -68,6 +68,9 @@ public: static void notificationActionReceivedJNI(JNIEnv *env, jobject /*thiz*/, jstring data); static void locationServicesEnabledChangedJNI(); +private: + void updateSafeAreaPadding(); + }; #endif // PLATFORMHELPERANDROID_H From 612397be6b5c69d0bf7cc1f83af526e978fc7e2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 25 Nov 2025 15:49:35 +0100 Subject: [PATCH 10/50] Add top padding also for the MainMenu --- nymea-app/platformintegration/android/platformhelperandroid.h | 2 ++ nymea-app/ui/MainMenu.qml | 1 + 2 files changed, 3 insertions(+) diff --git a/nymea-app/platformintegration/android/platformhelperandroid.h b/nymea-app/platformintegration/android/platformhelperandroid.h index bb60badd..8861f703 100644 --- a/nymea-app/platformintegration/android/platformhelperandroid.h +++ b/nymea-app/platformintegration/android/platformhelperandroid.h @@ -57,6 +57,8 @@ public: int topPadding() const override; int bottomPadding() const override; + int leftPadding() const override; + int rightPadding() const override; bool darkModeEnabled() const override; diff --git a/nymea-app/ui/MainMenu.qml b/nymea-app/ui/MainMenu.qml index 998369a4..543d5619 100644 --- a/nymea-app/ui/MainMenu.qml +++ b/nymea-app/ui/MainMenu.qml @@ -67,6 +67,7 @@ Drawer { ColumnLayout { anchors.fill: parent + anchors.topMargin: PlatformHelper.topPadding spacing: 0 Rectangle { From 3286fd154d9204b2667ac50a6dc76b29fb20e669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 25 Nov 2025 15:53:56 +0100 Subject: [PATCH 11/50] Android: Add left and right margins and handle cutout in the MainMenu --- .../io/guh/nymeaapp/NymeaAppActivity.java | 28 +++++++++++++++++++ .../android/platformhelperandroid.cpp | 19 ++++++++++++- nymea-app/ui/MainMenu.qml | 1 + 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/nymea-app/platformintegration/android/java/io/guh/nymeaapp/NymeaAppActivity.java b/nymea-app/platformintegration/android/java/io/guh/nymeaapp/NymeaAppActivity.java index 558482a9..40dbd4c2 100644 --- a/nymea-app/platformintegration/android/java/io/guh/nymeaapp/NymeaAppActivity.java +++ b/nymea-app/platformintegration/android/java/io/guh/nymeaapp/NymeaAppActivity.java @@ -178,6 +178,34 @@ public class NymeaAppActivity extends QtActivity return windowInsets.getStableInsetBottom(); } + public int leftPadding() { + WindowInsets windowInsets = getWindow().getDecorView().getRootWindowInsets(); + if (windowInsets == null) { + return 0; + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + Insets insets = windowInsets.getInsets(WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout()); + return insets != null ? insets.left : 0; + } + + return windowInsets.getStableInsetLeft(); + } + + public int rightPadding() { + WindowInsets windowInsets = getWindow().getDecorView().getRootWindowInsets(); + if (windowInsets == null) { + return 0; + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + Insets insets = windowInsets.getInsets(WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout()); + return insets != null ? insets.right : 0; + } + + return windowInsets.getStableInsetRight(); + } + private void logStaticInitClassesMetadata() { try { ApplicationInfo appInfo = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA); diff --git a/nymea-app/platformintegration/android/platformhelperandroid.cpp b/nymea-app/platformintegration/android/platformhelperandroid.cpp index a0455e2d..342c2d97 100644 --- a/nymea-app/platformintegration/android/platformhelperandroid.cpp +++ b/nymea-app/platformintegration/android/platformhelperandroid.cpp @@ -283,11 +283,15 @@ void PlatformHelperAndroid::updateSafeAreaPadding() { int topPaddingPx = 0; int bottomPaddingPx = 0; + int leftPaddingPx = 0; + int rightPaddingPx = 0; QJniObject context = QNativeInterface::QAndroidApplication::context(); if (context.isValid()) { topPaddingPx = context.callMethod("topPadding", "()I"); bottomPaddingPx = context.callMethod("bottomPadding", "()I"); + leftPaddingPx = context.callMethod("leftPadding", "()I"); + rightPaddingPx = context.callMethod("rightPadding", "()I"); } QScreen *screen = qApp->primaryScreen(); @@ -296,7 +300,10 @@ void PlatformHelperAndroid::updateSafeAreaPadding() dpr = 1.0; } - setSafeAreaPadding(qRound(topPaddingPx / dpr), 0, qRound(bottomPaddingPx / dpr), 0); + setSafeAreaPadding(qRound(topPaddingPx / dpr), + qRound(rightPaddingPx / dpr), + qRound(bottomPaddingPx / dpr), + qRound(leftPaddingPx / dpr)); } int PlatformHelperAndroid::topPadding() const @@ -309,6 +316,16 @@ int PlatformHelperAndroid::bottomPadding() const return PlatformHelper::bottomPadding(); } +int PlatformHelperAndroid::leftPadding() const +{ + return PlatformHelper::leftPadding(); +} + +int PlatformHelperAndroid::rightPadding() const +{ + return PlatformHelper::rightPadding(); +} + bool PlatformHelperAndroid::darkModeEnabled() const { return QNativeInterface::QAndroidApplication::context().callMethod("darkModeEnabled"); diff --git a/nymea-app/ui/MainMenu.qml b/nymea-app/ui/MainMenu.qml index 543d5619..6f521b55 100644 --- a/nymea-app/ui/MainMenu.qml +++ b/nymea-app/ui/MainMenu.qml @@ -68,6 +68,7 @@ Drawer { ColumnLayout { anchors.fill: parent anchors.topMargin: PlatformHelper.topPadding + anchors.leftMargin: PlatformHelper.leftPadding spacing: 0 Rectangle { From 7e6d1591b14af17866f8e8b67213604d34ae991e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 25 Nov 2025 16:06:07 +0100 Subject: [PATCH 12/50] Fix warning from missing inline media controller --- libnymea-app/models/tagsproxymodel.h | 4 ++-- nymea-app/ui/delegates/InterfaceTile.qml | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libnymea-app/models/tagsproxymodel.h b/libnymea-app/models/tagsproxymodel.h index 86c2d6b4..c6932d12 100644 --- a/libnymea-app/models/tagsproxymodel.h +++ b/libnymea-app/models/tagsproxymodel.h @@ -43,8 +43,8 @@ class TagsProxyModel : public QSortFilterProxyModel public: explicit TagsProxyModel(QObject *parent = nullptr); - Tags* tags() const; - void setTags(Tags* tags); + Tags *tags() const; + void setTags(Tags *tags); QString filterTagId() const; void setFilterTagId(const QString &filterTagId); diff --git a/nymea-app/ui/delegates/InterfaceTile.qml b/nymea-app/ui/delegates/InterfaceTile.qml index 6c587b22..b9f25472 100644 --- a/nymea-app/ui/delegates/InterfaceTile.qml +++ b/nymea-app/ui/delegates/InterfaceTile.qml @@ -233,7 +233,11 @@ MainPageTile { var d = thingsProxy.get(i); var st = d.thingClass.stateTypes.findByName("playbackStatus") var s = d.states.getState(st.id) - s.valueChanged.connect(function() {inlineMediaControl.updateTile()}) + s.valueChanged.connect(function() { + if (inlineMediaControl) { + inlineMediaControl.updateTile() + } + }) } updateTile(); } From 82aa5efe6f88813df7afdef403daab10c9b23c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 25 Nov 2025 16:09:13 +0100 Subject: [PATCH 13/50] Fix QML IconMenuItem: Created graphical object was not placed in the graphics scene. --- nymea-app/ui/components/ThingContextMenu.qml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/nymea-app/ui/components/ThingContextMenu.qml b/nymea-app/ui/components/ThingContextMenu.qml index ddfd1fcb..b8f4fcbd 100644 --- a/nymea-app/ui/components/ThingContextMenu.qml +++ b/nymea-app/ui/components/ThingContextMenu.qml @@ -34,7 +34,12 @@ AutoSizeMenu { property bool showDetails: true - Component.onCompleted: { + property bool menuItemsInitialized: false + + function ensureMenuItems() { + if (menuItemsInitialized) { + return; + } if (Configuration.magicEnabled) { root.addItem(menuEntryComponent.createObject(root, {text: qsTr("Magic"), iconSource: "qrc:/icons/magic.svg", functionName: "openThingMagicPage"})) } @@ -58,8 +63,6 @@ AutoSizeMenu { functionName: "addToGroup" })) - print("*** creating menu") - print("NFC", NfcHelper.isAvailable) if (NfcHelper.isAvailable) { root.addItem(menuEntryComponent.createObject(root, { @@ -69,6 +72,12 @@ AutoSizeMenu { })); } + menuItemsInitialized = true + } + + onAboutToShow: { + ensureMenuItems(); + calculateWidth(); } function openThingMagicPage() { From 0c663e9d495adc5d54daa4db77fc77639c889905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 25 Nov 2025 16:13:18 +0100 Subject: [PATCH 14/50] Fix NymeaDialog implicit width warning --- nymea-app/ui/components/NymeaDialog.qml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nymea-app/ui/components/NymeaDialog.qml b/nymea-app/ui/components/NymeaDialog.qml index eb64e977..8c34e166 100644 --- a/nymea-app/ui/components/NymeaDialog.qml +++ b/nymea-app/ui/components/NymeaDialog.qml @@ -25,11 +25,13 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts +import QtQuick.Window import Nymea Dialog { id: root - width: Math.min(parent.width * .8, Math.max(contentLabel.implicitWidth, 400)) + implicitWidth: Math.max(contentLabel.implicitWidth + app.margins * 2, 400) + width: Math.min((parent ? parent.width : Screen.width) * .8, implicitWidth) x: (parent.width - width) / 2 y: (parent.height - height) / 2 From 12b11fca1a4ca11f148bdc431ef218cc9b0b9f41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 26 Nov 2025 12:02:50 +0100 Subject: [PATCH 15/50] Update imprint and add detailed open source license information --- nymea-app/main.cpp | 1 + nymea-app/ui/components/LicenseInformationItem.qml | 11 +++++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/nymea-app/main.cpp b/nymea-app/main.cpp index a1059530..1acb1832 100644 --- a/nymea-app/main.cpp +++ b/nymea-app/main.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/nymea-app/ui/components/LicenseInformationItem.qml b/nymea-app/ui/components/LicenseInformationItem.qml index ce1435c0..651cc0f6 100644 --- a/nymea-app/ui/components/LicenseInformationItem.qml +++ b/nymea-app/ui/components/LicenseInformationItem.qml @@ -22,12 +22,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Controls.Material 2.2 -import QtQuick.Layouts 1.3 -import Nymea 1.0 - +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material +import Nymea NymeaSwipeDelegate { id: root From fb42ea6c0438e15cdaed7f84d19d031232d3a6fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 26 Nov 2025 13:47:31 +0100 Subject: [PATCH 16/50] Update android packaging for Qt6 qmake handling with arch individual aab --- packaging/android/build.gradle | 38 +++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/packaging/android/build.gradle b/packaging/android/build.gradle index 16e86bd3..8a0b0275 100644 --- a/packaging/android/build.gradle +++ b/packaging/android/build.gradle @@ -5,6 +5,27 @@ properties.load(project.rootProject.file("nymeaapp.properties").newDataInputStre def nymeaAppRoot = properties.getProperty('nymeaAppRoot') def useFirebase = properties.getProperty('useFirebase') +def nymeaVersionLines = file("${nymeaAppRoot}/version.txt").readLines().collect { it.trim() }.findAll { it } +def nymeaAppVersionName = nymeaVersionLines ? nymeaVersionLines[0] : "0.0.0" +def nymeaAppBaseVersionCode = nymeaVersionLines.size() > 1 ? nymeaVersionLines[1].toInteger() : 1 + +// Use ABI-aware version codes per Qt's legacy single-ABI Play Store guidance. +def abiVersionPrefixes = [ + "armeabi-v7a": "132", + "arm64-v8a" : "164", + "x86" : "232", + "x86_64" : "264" +] + +def qtTargetAbiListValue = project.hasProperty('qtTargetAbiList') ? qtTargetAbiList : "" +def targetAbiList = qtTargetAbiListValue.split(",").collect { it.trim() }.findAll { it } +def singleTargetAbi = targetAbiList.size() == 1 ? targetAbiList[0] : null +def computeAbiVersionCode = { abi, baseCode -> + def prefix = abiVersionPrefixes[abi] + return prefix ? Integer.parseInt("${prefix}${baseCode}") : baseCode +} +def nymeaDefaultVersionCode = computeAbiVersionCode(singleTargetAbi, nymeaAppBaseVersionCode) + println "Building Android package" println "Package source root ${nymeaAppRoot}" @@ -127,6 +148,21 @@ android { resConfigs "en", "de", "ko", "it", "nl", "es" minSdkVersion = 23 targetSdkVersion = 35 - ndk.abiFilters = qtTargetAbiList.split(",") + ndk.abiFilters = targetAbiList + versionName nymeaAppVersionName + versionCode nymeaDefaultVersionCode } } + +androidComponents { + onVariants(selector().all(), { variant -> + variant.outputs.forEach { output -> + def abiFilter = output.filters.find { it.filterType == com.android.build.api.variant.FilterConfiguration.FilterType.ABI }?.identifier + if (abiFilter != null) { + output.versionCode.set(computeAbiVersionCode(abiFilter, nymeaAppBaseVersionCode)) + } else if (singleTargetAbi != null) { + output.versionCode.set(nymeaDefaultVersionCode) + } + } + }) +} From 3b7a97a5f533c3859f5043b996dead903a5ee4db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 26 Nov 2025 13:48:18 +0100 Subject: [PATCH 17/50] Android: target SDK 36 --- packaging/android/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/android/build.gradle b/packaging/android/build.gradle index 8a0b0275..2fdf328c 100644 --- a/packaging/android/build.gradle +++ b/packaging/android/build.gradle @@ -147,7 +147,7 @@ android { defaultConfig { resConfigs "en", "de", "ko", "it", "nl", "es" minSdkVersion = 23 - targetSdkVersion = 35 + targetSdkVersion = 36 ndk.abiFilters = targetAbiList versionName nymeaAppVersionName versionCode nymeaDefaultVersionCode From 8ab31af5494be691be85794b43ce864d53ca9581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 26 Nov 2025 14:16:36 +0100 Subject: [PATCH 18/50] iOS: Add initial cmake apptempt --- CMakeLists.txt | 4 ++ nymea-app/CMakeLists.txt | 70 ++++++++++++++++++++++++++++++- packaging/ios/Info.plist.cmake.in | 66 +++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 packaging/ios/Info.plist.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt index b65ad56b..0d88e833 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,10 @@ endif() project(nymea-app VERSION ${NYMEA_APP_VERSION} LANGUAGES CXX) +if(IOS) + enable_language(OBJCXX) +endif() + set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) diff --git a/nymea-app/CMakeLists.txt b/nymea-app/CMakeLists.txt index f844da89..62489779 100644 --- a/nymea-app/CMakeLists.txt +++ b/nymea-app/CMakeLists.txt @@ -52,6 +52,20 @@ if(ANDROID) ) endif() +if(IOS) + list(APPEND NYMEA_APP_SOURCES + platformintegration/ios/platformhelperios.cpp + platformintegration/ios/platformpermissionsios.cpp + platformintegration/ios/platformhelperios.mm + platformintegration/ios/pushnotifications.mm + platformintegration/ios/platformpermissionsios.mm + ) + list(APPEND NYMEA_APP_HEADERS + platformintegration/ios/platformhelperios.h + platformintegration/ios/platformpermissionsios.h + ) +endif() + set(NYMEA_APP_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/resources.qrc ${CMAKE_CURRENT_SOURCE_DIR}/ruletemplates.qrc @@ -149,5 +163,59 @@ if(ANDROID) endif() endif() -qt_finalize_executable(nymea-app) +if(IOS) + target_link_libraries(nymea-app PRIVATE + "-framework CoreLocation" + "-framework CoreBluetooth" + "-framework CoreNFC" + ) + set(_nymea_ios_plist "${CMAKE_CURRENT_BINARY_DIR}/ios/Info.plist") + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/ios") + configure_file( + ${CMAKE_SOURCE_DIR}/packaging/ios/Info.plist.cmake.in + ${_nymea_ios_plist} + @ONLY + ) + + set_target_properties(nymea-app PROPERTIES + MACOSX_BUNDLE_INFO_PLIST "${_nymea_ios_plist}" + MACOSX_BUNDLE_GUI_IDENTIFIER "io.guh.nymeaApp" + MACOSX_BUNDLE_BUNDLE_VERSION "${APP_REVISION}" + MACOSX_BUNDLE_SHORT_VERSION_STRING "${APP_VERSION}" + XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_SOURCE_DIR}/packaging/ios/app.entitlements" + ) + + target_link_options(nymea-app PRIVATE "-ObjC") + + set_property(TARGET nymea-app APPEND PROPERTY + QT_IOS_ASSET_CATALOGS "${CMAKE_SOURCE_DIR}/packaging/ios/Assets.xcassets") + + set(_nymea_ios_resources + ${CMAKE_SOURCE_DIR}/packaging/ios/NymeaLaunchScreen.storyboard + ${CMAKE_SOURCE_DIR}/packaging/ios/GoogleService-Info.plist + ) + set_source_files_properties(${_nymea_ios_resources} PROPERTIES + MACOSX_PACKAGE_LOCATION Resources) + target_sources(nymea-app PRIVATE ${_nymea_ios_resources}) + + if(NYMEA_ENABLE_FIREBASE) + target_compile_definitions(nymea-app PRIVATE WITH_FIREBASE FIREBASE_ANALYTICS_SUPPRESS_WARNING) + target_include_directories(nymea-app PRIVATE ${CMAKE_SOURCE_DIR}/3rdParty/ios) + target_link_directories(nymea-app PRIVATE + ${CMAKE_SOURCE_DIR}/3rdParty/ios/Firebase/FirebaseAnalytics + ${CMAKE_SOURCE_DIR}/3rdParty/ios/Firebase/FirebaseMessaging + ) + target_link_libraries(nymea-app PRIVATE + "-framework FirebaseMessaging" + "-framework GoogleUtilities" + "-framework Protobuf" + "-framework FirebaseCore" + "-framework FirebaseInstanceID" + "-framework FirebaseInstallations" + "-framework PromisesObjC" + ) + endif() +endif() + +qt_finalize_executable(nymea-app) diff --git a/packaging/ios/Info.plist.cmake.in b/packaging/ios/Info.plist.cmake.in new file mode 100644 index 00000000..54c03110 --- /dev/null +++ b/packaging/ios/Info.plist.cmake.in @@ -0,0 +1,66 @@ + + + + + CFBundleDisplayName + nymea:app + CFBundleExecutable + nymea-app + CFBundleGetInfoString + Created by Qt/CMake + CFBundleIdentifier + io.guh.nymeaApp + CFBundleName + nymea-app + CFBundlePackageType + APPL + CFBundleShortVersionString + @APP_VERSION@ + CFBundleSignature + ???? + CFBundleVersion + @APP_REVISION@ + LSRequiresIPhoneOS + + NOTE + This file was generated by Qt/CMake. + UILaunchStoryboardName + NymeaLaunchScreen + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + NSBluetoothPeripheralUsageDescription + nymea boxes can be connected to WiFi using a Bluetooth setup. Also, this app can connect to nymea boxes using Bluetooth only, without requiring WiFi at all. + NSBluetoothAlwaysUsageDescription + nymea boxes can be connected to WiFi using a Bluetooth setup. Also, this app can connect to nymea boxes using Bluetooth only, without requiring WiFi at all. + NSLocalNetworkUsageDescription + nymea:app will connect to nymea systems in the local network and allow controlling smart home equipment. + NSLocationWhenInUseUsageDescription + nymea:app is not using the device location at this point. + NSLocationAlwaysAndWhenInUseUsageDescription + nymea:app is not using the device location at this point. + NSBonjourServices + + _jsonrpc._tcp + _ws._tcp + + UIViewControllerBasedStatusBarAppearance + + XSAppIconAssets + AppIcons.xcassets/AppIcon.appiconset + CFBundleIconFiles + + AppIcon29x29.png + AppIcon29x29@2x.png + AppIcon40x40@2x.png + AppIcon60x60@2x.png + AppIcon83.5x83.5@2x.png + + ITSAppUsesNonExemptEncryption + + + From e705de8675b964665622e774d2b89a5d911cae30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 26 Nov 2025 14:25:29 +0100 Subject: [PATCH 19/50] iOS: Enable SSL for lan --- packaging/ios/Info.plist.in | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packaging/ios/Info.plist.in b/packaging/ios/Info.plist.in index 91ca1970..69e4422b 100644 --- a/packaging/ios/Info.plist.in +++ b/packaging/ios/Info.plist.in @@ -48,6 +48,14 @@ _jsonrpc._tcp _ws._tcp + NSAppTransportSecurity + + + NSAllowsArbitraryLoads + + NSAllowsLocalNetworking + + UIViewControllerBasedStatusBarAppearance XSAppIconAssets From f2229ba321b2431885a1f80ff4f84abc1dbd8496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Thu, 27 Nov 2025 11:42:15 +0100 Subject: [PATCH 20/50] Android: Fix edge-to-edge for android SKD < 35 --- .../java/io/guh/nymeaapp/NymeaAppActivity.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/nymea-app/platformintegration/android/java/io/guh/nymeaapp/NymeaAppActivity.java b/nymea-app/platformintegration/android/java/io/guh/nymeaapp/NymeaAppActivity.java index 40dbd4c2..6345d2e1 100644 --- a/nymea-app/platformintegration/android/java/io/guh/nymeaapp/NymeaAppActivity.java +++ b/nymea-app/platformintegration/android/java/io/guh/nymeaapp/NymeaAppActivity.java @@ -150,6 +150,10 @@ public class NymeaAppActivity extends QtActivity } public int topPadding() { + if (Build.VERSION.SDK_INT < 35) { + return 0; + } + WindowInsets windowInsets = getWindow().getDecorView().getRootWindowInsets(); if (windowInsets == null) { @@ -165,6 +169,10 @@ public class NymeaAppActivity extends QtActivity } public int bottomPadding() { + if (Build.VERSION.SDK_INT < 35) { + return 0; + } + WindowInsets windowInsets = getWindow().getDecorView().getRootWindowInsets(); if (windowInsets == null) { return 0; @@ -179,6 +187,10 @@ public class NymeaAppActivity extends QtActivity } public int leftPadding() { + if (Build.VERSION.SDK_INT < 35) { + return 0; + } + WindowInsets windowInsets = getWindow().getDecorView().getRootWindowInsets(); if (windowInsets == null) { return 0; @@ -193,6 +205,10 @@ public class NymeaAppActivity extends QtActivity } public int rightPadding() { + if (Build.VERSION.SDK_INT < 35) { + return 0; + } + WindowInsets windowInsets = getWindow().getDecorView().getRootWindowInsets(); if (windowInsets == null) { return 0; From 120e6d29074eea8cd8ee703830cbccd515b0bc83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Thu, 27 Nov 2025 13:52:53 +0100 Subject: [PATCH 21/50] Update energy charts and fix y value texts --- .../ui/mainviews/energy/ConsumerStats.qml | 12 ++++++--- .../ui/mainviews/energy/ConsumersHistory.qml | 14 ++++++---- .../mainviews/energy/PowerBalanceHistory.qml | 26 ++++++++++++------- .../ui/mainviews/energy/PowerBalanceStats.qml | 12 ++++++--- .../energy/PowerConsumptionBalanceHistory.qml | 15 +++++++---- .../energy/PowerProductionBalanceHistory.qml | 15 +++++++---- 6 files changed, 63 insertions(+), 31 deletions(-) diff --git a/nymea-app/ui/mainviews/energy/ConsumerStats.qml b/nymea-app/ui/mainviews/energy/ConsumerStats.qml index 60c3d855..e1d1a24f 100644 --- a/nymea-app/ui/mainviews/energy/ConsumerStats.qml +++ b/nymea-app/ui/mainviews/energy/ConsumerStats.qml @@ -247,7 +247,7 @@ StatsBase { anchors.fill: parent backgroundColor: "transparent" - // margins.left: 0 + margins.left: Math.max(Style.smallMargins * 2, valueLabelMetrics.width + Style.smallMargins * 2) margins.right: 0 margins.top: 0 margins.bottom: Style.smallIconSize + Style.margins @@ -291,12 +291,18 @@ StatsBase { Behavior on opacity { NumberAnimation {}} } + TextMetrics { + id: valueLabelMetrics + font: Style.extraSmallFont + text: (valueAxis.max).toFixed(1) + "kWh" + } + Item { id: labelsLayout x: Style.smallMargins y: chartView.plotArea.y height: chartView.plotArea.height - width: chartView.plotArea.x - x + width: Math.max(0, chartView.margins.left - Style.smallMargins) Repeater { model: valueAxis.tickCount delegate: Label { @@ -484,7 +490,7 @@ StatsBase { } property int wheelDelta: 0 - onWheel: { + onWheel: (wheel) => { wheelDelta += wheel.pixelDelta.x var slotWidth = mouseArea.width / d.config.count while (wheelDelta > slotWidth) { diff --git a/nymea-app/ui/mainviews/energy/ConsumersHistory.qml b/nymea-app/ui/mainviews/energy/ConsumersHistory.qml index 2324f4b7..113059c7 100644 --- a/nymea-app/ui/mainviews/energy/ConsumersHistory.qml +++ b/nymea-app/ui/mainviews/energy/ConsumersHistory.qml @@ -61,7 +61,7 @@ Item { } } - onEntriesRemoved: { + onEntriesRemoved: (index, count) => { consumptionUpperSeries.removePoints(index, Math.min(count, consumptionUpperSeries.count)) zeroSeries.shrink() } @@ -227,7 +227,7 @@ Item { anchors.fill: parent backgroundColor: "transparent" - margins.left: 0 + margins.left: Math.max(Style.smallMargins * 2, valueLabelMetrics.width + Style.smallMargins * 2) margins.right: 0 margins.top: 0 margins.bottom: Style.smallIconSize + Style.margins @@ -252,6 +252,11 @@ Item { opacity: .5 } + TextMetrics { + id: valueLabelMetrics + font: Style.extraSmallFont + text: ((valueAxis.max) / 1000).toFixed(2) + "kW" + } ValueAxis { id: valueAxis @@ -263,7 +268,6 @@ Item { lineVisible: false titleVisible: false shadesVisible: false - // visible: false function adjustMax(value) { max = Math.max(max, Math.ceil(value / 100) * 100) @@ -275,7 +279,7 @@ Item { x: Style.smallMargins y: chartView.plotArea.y height: chartView.plotArea.height - width: chartView.plotArea.x - x + width: Math.max(0, chartView.margins.left - Style.smallMargins) Repeater { model: valueAxis.tickCount delegate: Label { @@ -692,7 +696,7 @@ Item { d.now = new Date(Math.min(new Date(), new Date(startDatetime.getTime() + timeDelta))) } - onWheel: { + onWheel: (wheel) => { startDatetime = d.now var totalTime = d.endTime.getTime() - d.startTime.getTime() // pixelDelta : timeDelta = width : totalTime diff --git a/nymea-app/ui/mainviews/energy/PowerBalanceHistory.qml b/nymea-app/ui/mainviews/energy/PowerBalanceHistory.qml index 961dfaf0..0276cab1 100644 --- a/nymea-app/ui/mainviews/energy/PowerBalanceHistory.qml +++ b/nymea-app/ui/mainviews/energy/PowerBalanceHistory.qml @@ -94,7 +94,7 @@ Item { } function selectSeries(series) { - if (d.selectedSeries == series) { + if (d.selectedSeries === series) { d.selectedSeries = null } else { d.selectedSeries = series @@ -147,7 +147,7 @@ Item { acquisitionSeries.lowerSeries = fromStorageUpperSeries } - onEntriesRemoved: { + onEntriesRemoved: (index, count) => { // Note QtCharts crash when calling removePoints() for points that don't exist. // Additionally it may decide to ignore values we add, e.g. if we try to add an Inf or undefined value for whatever reason // So, even though in theory the series should always 1:1 reflect the model, it may not do so in practice and we'll have to make sure not crash here @@ -246,7 +246,7 @@ Item { id: chartView anchors.fill: parent backgroundColor: "transparent" - margins.left: 0 + margins.left: Math.max(Style.smallMargins * 2, valueLabelMetrics.width + Style.smallMargins * 2) margins.right: 0 margins.bottom: Style.smallIconSize + Style.margins margins.top: 0 @@ -259,18 +259,24 @@ Item { ActivityIndicator { x: chartView.plotArea.x + (chartView.plotArea.width - width) / 2 y: chartView.plotArea.y + (chartView.plotArea.height - height) / 2 + (chartView.plotArea.height / 8) - visible: powerBalanceLogs.fetchingData && (powerBalanceLogs.count == 0 || powerBalanceLogs.get(0).timestamp > d.startTime) + visible: powerBalanceLogs.fetchingData && (powerBalanceLogs.count === 0 || powerBalanceLogs.get(0).timestamp > d.startTime) opacity: .5 } Label { x: chartView.plotArea.x + (chartView.plotArea.width - width) / 2 y: chartView.plotArea.y + (chartView.plotArea.height - height) / 2 + (chartView.plotArea.height / 8) text: qsTr("No data available") - visible: !powerBalanceLogs.fetchingData && (powerBalanceLogs.count == 0 || powerBalanceLogs.get(0).timestamp > d.now) + visible: !powerBalanceLogs.fetchingData && (powerBalanceLogs.count === 0 || powerBalanceLogs.get(0).timestamp > d.now) font: Style.smallFont opacity: .5 } + TextMetrics { + id: valueLabelMetrics + font: Style.extraSmallFont + text: ((valueAxis.max) / 1000).toFixed(2) + "kW" + } + ValueAxis { id: valueAxis min: 0 @@ -282,12 +288,13 @@ Item { titleVisible: false shadesVisible: false } + Item { id: labelsLayout x: Style.smallMargins y: chartView.plotArea.y height: chartView.plotArea.height - width: chartView.plotArea.x - x + width: Math.max(0, chartView.margins.left - Style.smallMargins) Repeater { model: valueAxis.tickCount delegate: Label { @@ -353,9 +360,9 @@ Item { XYPoint { x: dateTimeAxis.min.getTime(); y: 0 } XYPoint { x: dateTimeAxis.max.getTime(); y: 0 } function ensureValue(timestamp) { - if (count == 0) { + if (count === 0) { append(timestamp, 0) - } else if (count == 1) { + } else if (count === 1) { if (timestamp.getTime() < at(0).x) { insert(0, timestamp, 0) } else { @@ -813,7 +820,7 @@ Item { d.now = new Date(Math.min(new Date(), new Date(startDatetime.getTime() + timeDelta))) } - onWheel: { + onWheel: (wheel) => { startDatetime = d.now var totalTime = d.endTime.getTime() - d.startTime.getTime() // pixelDelta : timeDelta = width : totalTime @@ -966,4 +973,3 @@ Item { } - diff --git a/nymea-app/ui/mainviews/energy/PowerBalanceStats.qml b/nymea-app/ui/mainviews/energy/PowerBalanceStats.qml index 93f006eb..17da03e5 100644 --- a/nymea-app/ui/mainviews/energy/PowerBalanceStats.qml +++ b/nymea-app/ui/mainviews/energy/PowerBalanceStats.qml @@ -242,7 +242,7 @@ StatsBase { legend.font: Style.extraSmallFont legend.labelColor: Style.foregroundColor - // margins.left: 0 + margins.left: Math.max(Style.smallMargins * 2, valueLabelMetrics.width + Style.smallMargins * 2) margins.right: 0 margins.bottom: Style.smallIconSize + Style.margins margins.top: 0 @@ -263,12 +263,18 @@ StatsBase { Behavior on opacity { NumberAnimation {}} } + TextMetrics { + id: valueLabelMetrics + font: Style.extraSmallFont + text: (valueAxis.max).toFixed(1) + "kWh" + } + Item { id: labelsLayout x: Style.smallMargins y: chartView.plotArea.y height: chartView.plotArea.height - width: chartView.plotArea.x - x + width: Math.max(0, chartView.margins.left - Style.smallMargins) Repeater { model: valueAxis.tickCount @@ -615,7 +621,7 @@ StatsBase { } property int wheelDelta: 0 - onWheel: { + onWheel: (wheel) => { wheelDelta += wheel.pixelDelta.x var slotWidth = mouseArea.width / d.config.count while (wheelDelta > slotWidth) { diff --git a/nymea-app/ui/mainviews/energy/PowerConsumptionBalanceHistory.qml b/nymea-app/ui/mainviews/energy/PowerConsumptionBalanceHistory.qml index 703753d5..89c61995 100644 --- a/nymea-app/ui/mainviews/energy/PowerConsumptionBalanceHistory.qml +++ b/nymea-app/ui/mainviews/energy/PowerConsumptionBalanceHistory.qml @@ -110,7 +110,7 @@ Item { } } - onEntriesRemoved: { + onEntriesRemoved: (index, count) => { acquisitionUpperSeries.removePoints(index, count) storageUpperSeries.removePoints(index, count) selfProductionUpperSeries.removePoints(index, count) @@ -194,7 +194,7 @@ Item { id: chartView anchors.fill: parent backgroundColor: "transparent" - margins.left: 0 + margins.left: Math.max(Style.smallMargins * 2, valueLabelMetrics.width + Style.smallMargins * 2) margins.right: 0 margins.bottom: 0 margins.top: 0 @@ -218,6 +218,12 @@ Item { opacity: .5 } + TextMetrics { + id: valueLabelMetrics + font: Style.extraSmallFont + text: ((valueAxis.max) / 1000).toFixed(2) + "kW" + } + ValueAxis { id: valueAxis min: 0 @@ -237,7 +243,7 @@ Item { x: Style.smallMargins y: chartView.plotArea.y height: chartView.plotArea.height - width: chartView.plotArea.x - x + width: Math.max(0, chartView.margins.left - Style.smallMargins) Repeater { model: valueAxis.tickCount delegate: Label { @@ -502,7 +508,7 @@ Item { d.now = new Date(Math.min(new Date(), new Date(startDatetime.getTime() + timeDelta))) } - onWheel: { + onWheel: (wheel) => { startDatetime = d.now var totalTime = d.endTime.getTime() - d.startTime.getTime() // pixelDelta : timeDelta = width : totalTime @@ -630,4 +636,3 @@ Item { } } } - diff --git a/nymea-app/ui/mainviews/energy/PowerProductionBalanceHistory.qml b/nymea-app/ui/mainviews/energy/PowerProductionBalanceHistory.qml index 4b16fcca..aab7f48c 100644 --- a/nymea-app/ui/mainviews/energy/PowerProductionBalanceHistory.qml +++ b/nymea-app/ui/mainviews/energy/PowerProductionBalanceHistory.qml @@ -111,7 +111,7 @@ Item { } } - onEntriesRemoved: { + onEntriesRemoved: (index, count) => { acquisitionUpperSeries.removePoints(index, count) storageUpperSeries.removePoints(index, count) selfConsumptionUpperSeries.removePoints(index, count) @@ -195,7 +195,7 @@ Item { id: chartView anchors.fill: parent backgroundColor: "transparent" - margins.left: 0 + margins.left: Math.max(Style.smallMargins * 2, valueLabelMetrics.width + Style.smallMargins * 2) margins.right: 0 margins.bottom: 0 margins.top: 0 @@ -219,6 +219,12 @@ Item { opacity: .5 } + TextMetrics { + id: valueLabelMetrics + font: Style.extraSmallFont + text: ((valueAxis.max) / 1000).toFixed(2) + "kW" + } + ValueAxis { id: valueAxis min: 0 @@ -235,7 +241,7 @@ Item { x: Style.smallMargins y: chartView.plotArea.y height: chartView.plotArea.height - width: chartView.plotArea.x - x + width: Math.max(0, chartView.margins.left - Style.smallMargins) Repeater { model: valueAxis.tickCount delegate: Label { @@ -495,7 +501,7 @@ Item { d.now = new Date(Math.min(new Date(), new Date(startDatetime.getTime() + timeDelta))) } - onWheel: { + onWheel: (wheel) => { startDatetime = d.now var totalTime = d.endTime.getTime() - d.startTime.getTime() // pixelDelta : timeDelta = width : totalTime @@ -627,4 +633,3 @@ Item { } - From 8895a853a73e7cdd6d7415905f0fe2242308743d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Thu, 27 Nov 2025 13:53:45 +0100 Subject: [PATCH 22/50] Update some signal handlers to JavaScript functions with formal parameters Update translations Bump build revision --- nymea-app/ruletemplates/messages.h | 24 --- nymea-app/translations/nymea-app.cs.ts | 154 +++++++++++------ nymea-app/translations/nymea-app.de.ts | 156 ++++++++++++------ nymea-app/translations/nymea-app.en.ts | 152 +++++++++++------ nymea-app/translations/nymea-app.en_US.ts | 152 +++++++++++------ nymea-app/translations/nymea-app.it.ts | 152 +++++++++++------ nymea-app/translations/nymea-app.ko.ts | 154 +++++++++++------ nymea-app/translations/nymea-app.nl.ts | 154 +++++++++++------ nymea-app/translations/nymea-app.tr.ts | 154 +++++++++++------ nymea-app/translations/nymea-app.vi.ts | 152 +++++++++++------ nymea-app/ui/customviews/GenericTypeGraph.qml | 2 +- nymea-app/ui/customviews/MultiStateChart.qml | 4 +- nymea-app/ui/customviews/StateChart.qml | 2 +- nymea-app/ui/mainviews/EnergyView.qml | 1 - .../airconditioning/ACChartsPage.qml | 48 +++--- .../energy/CurrentPowerBalancePage.qml | 4 +- .../zigbee/ZigbeeNetworkTopologyPage.qml | 2 +- version.txt | 2 +- 18 files changed, 992 insertions(+), 477 deletions(-) diff --git a/nymea-app/ruletemplates/messages.h b/nymea-app/ruletemplates/messages.h index 46ba7ad9..8d4b3528 100644 --- a/nymea-app/ruletemplates/messages.h +++ b/nymea-app/ruletemplates/messages.h @@ -1,27 +1,3 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright (C) 2013 - 2024, nymea GmbH -* Copyright (C) 2024 - 2025, chargebyte austria GmbH -* -* This file is part of nymea-app. -* -* nymea-app is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* nymea-app is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with nymea-app. If not, see . -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - // This file is generated. Update it using ./messages.sh in the root source directory #include const QString translations[] { diff --git a/nymea-app/translations/nymea-app.cs.ts b/nymea-app/translations/nymea-app.cs.ts index 8f583159..b6300fde 100644 --- a/nymea-app/translations/nymea-app.cs.ts +++ b/nymea-app/translations/nymea-app.cs.ts @@ -104,34 +104,6 @@ App version: App verze: - - Qt version: - Qt verze: - - - Built with %1 - Vytvořeno s %1 - - - Suru icons by Ubuntu - Ikony Suru z Ubuntu - - - Ubuntu font by Ubuntu - Písmo Ubuntu - - - QtZeroConf library by Jonathan Bagg - Knihovna QtZeroConf od Jonathana Bagga - - - OpenSSL libraries by Eric Young - Knihovna OpenSSL od Erica Younga - - - Oswald font by The Oswald Project - Písmo Oswald z "The Oswald Project" - ActionLogPage @@ -589,10 +561,6 @@ Telegram Telegram - - Discord - Discord - ConfigureThingPage @@ -2543,10 +2511,6 @@ Prosím zkuste to znovu. Howdy cowboy! Nazdar kovboji! - - Visit the nymea website - Navštivte webovou stránku nymea - Visit GitHub page Navštivte stránku GitHub @@ -2555,14 +2519,6 @@ Prosím zkuste to znovu. View privacy policy Zobrazit zásady ochrany osobních údajů - - Qt is a registered trademark of The Qt Company Ltd. and its subsidiaries. - Qt je registrovaná ochranná známka společnosti The Qt Company Ltd. - - - Visit the Qt website - Navštivte web Qt - Licensed under the terms of the GNU General Public License, version 3. Please visit the GitHub page for source code and build instructions. Licencováno podle podmínek GNU General Public License, verze 3. Navštivte prosím stránku GitHub, kde najdete zdrojový kód a pokyny k sestavení. @@ -2576,11 +2532,115 @@ Prosím zkuste to znovu. Další softwarové licence - nymea is a registered trademark of chargebyte GmbH. - nymea je registrovaná ochranná známka společnosti chargebyte GmbH. + nymea is a registered trademark of chargebyte austria GmbH. + - Licensed under the terms of the nymea commercial license. + chargebyte GmbH + + + + Visit the nymea project website + + + + Open Source Licenses + + + + Qt core module + + + + Qt gui module + + + + Qt network module + + + + Qt QML module + + + + Qt Quick module + + + + Qt Quick Controls module + + + + Qt Quick Dialogs module + + + + Qt Quick Layouts module + + + + Qt 5 compatibility module + + + + Qt image formats module + + + + Qt SVG module + + + + Qt charts module + + + + Qt websockets module + + + + Qt bluetooth module + + + + Qt NFC module + + + + Client library for remote connections + + + + QtZeroConf library by Jonathan Bagg + Knihovna QtZeroConf od Jonathana Bagga + + + Firebase iOS SDK + + + + Firebase Android SDK + + + + OpenSSL libraries by Eric Young + Knihovna OpenSSL od Erica Younga + + + Suru icons by Ubuntu + Ikony Suru z Ubuntu + + + Ubuntu font by Ubuntu + Písmo Ubuntu + + + Oswald font by The Oswald Project + Písmo Oswald z "The Oswald Project" + + + Google fonts and material icons diff --git a/nymea-app/translations/nymea-app.de.ts b/nymea-app/translations/nymea-app.de.ts index 0cc02758..c2952d2a 100644 --- a/nymea-app/translations/nymea-app.de.ts +++ b/nymea-app/translations/nymea-app.de.ts @@ -104,34 +104,6 @@ App version: App Version: - - Qt version: - Qt Version: - - - Built with %1 - Erstellt mit %1 - - - Suru icons by Ubuntu - Suru Icons von Ubuntu - - - Ubuntu font by Ubuntu - Ubuntu Schrift von Ubuntu - - - QtZeroConf library by Jonathan Bagg - QtZeroConf Bibliothek von Jonathan Bagg - - - OpenSSL libraries by Eric Young - OpenSSL Bibliothek von Eric Young - - - Oswald font by The Oswald Project - Oswald Schrift von "The Oswald Project" - ActionLogPage @@ -588,10 +560,6 @@ Telegram Telegram - - Discord - Discord - ConfigureThingPage @@ -2535,10 +2503,6 @@ Bitte versuche es erneut. Howdy cowboy! Howdy cowboy! - - Visit the nymea website - Besuchen Sie die nymea Webseite - Visit GitHub page Besuchen Sie die GitHub Seite @@ -2547,14 +2511,6 @@ Bitte versuche es erneut. View privacy policy Datenschutzerklärung anzeigen - - Qt is a registered trademark of The Qt Company Ltd. and its subsidiaries. - Qt ist ein eingetragenes Markenzeichen von The Qt Company Ltd. - - - Visit the Qt website - Besuchen Sie die Qt Webseite - Licensed under the terms of the GNU General Public License, version 3. Please visit the GitHub page for source code and build instructions. Lizensiert unter den Bedingungen der GNU General Public License, Version 3. Bitte besuche die GitHub Seite für mehr Informationen zum Quellcode und Kompilier-Anleitungen. @@ -2568,12 +2524,116 @@ Bitte versuche es erneut. Zusätzliche Software-Lizenzen - nymea is a registered trademark of chargebyte GmbH. - nymea ist ein eingetragenes Markenzeichen von chargebyte GmbH. + nymea is a registered trademark of chargebyte austria GmbH. + nymea ist eine eingetragene Marke der chargebyte austria GmbH. - Licensed under the terms of the nymea commercial license. - Lizensiert unter den Bedingungen der kommerzielle Lizenz von Nymea. + chargebyte GmbH + chargebyte GmbH + + + Visit the nymea project website + Besuchen Sie die nymea-Projektwebseite + + + Open Source Licenses + Open-Source-Lizenzen + + + Qt core module + Qt Core-Modul + + + Qt gui module + Qt GUI-Modul + + + Qt network module + Qt Netzwerkmodul + + + Qt QML module + Qt QML-Modul + + + Qt Quick module + Qt Quick-Modul + + + Qt Quick Controls module + Qt Quick Controls-Modul + + + Qt Quick Dialogs module + Qt Quick Dialogs-Modul + + + Qt Quick Layouts module + Qt Quick Layouts-Modul + + + Qt 5 compatibility module + Qt 5-Kompatibilitätsmodul + + + Qt image formats module + Qt Bildformate-Modul + + + Qt SVG module + Qt SVG-Modul + + + Qt charts module + Qt Charts-Modul + + + Qt websockets module + Qt WebSockets-Modul + + + Qt bluetooth module + Qt Bluetooth-Modul + + + Qt NFC module + Qt NFC-Modul + + + Client library for remote connections + Client-Bibliothek für Remote-Verbindungen + + + QtZeroConf library by Jonathan Bagg + QtZeroConf-Bibliothek von Jonathan Bagg + + + Firebase iOS SDK + Firebase iOS-SDK + + + Firebase Android SDK + Firebase Android-SDK + + + OpenSSL libraries by Eric Young + OpenSSL-Bibliotheken von Eric Young + + + Suru icons by Ubuntu + Suru-Icons von Ubuntu + + + Ubuntu font by Ubuntu + Ubuntu-Schrift von Ubuntu + + + Oswald font by The Oswald Project + Oswald-Schrift von "The Oswald Project" + + + Google fonts and material icons + Google Fonts und Material Icons diff --git a/nymea-app/translations/nymea-app.en.ts b/nymea-app/translations/nymea-app.en.ts index 4e478cc2..45c478e8 100644 --- a/nymea-app/translations/nymea-app.en.ts +++ b/nymea-app/translations/nymea-app.en.ts @@ -104,34 +104,6 @@ App version: - - Qt version: - - - - Built with %1 - - - - Suru icons by Ubuntu - - - - Ubuntu font by Ubuntu - - - - QtZeroConf library by Jonathan Bagg - - - - OpenSSL libraries by Eric Young - - - - Oswald font by The Oswald Project - - ActionLogPage @@ -588,10 +560,6 @@ Telegram - - Discord - - ConfigureThingPage @@ -2528,10 +2496,6 @@ Please try again. Howdy cowboy! - - Visit the nymea website - - Visit GitHub page @@ -2540,14 +2504,6 @@ Please try again. View privacy policy - - Qt is a registered trademark of The Qt Company Ltd. and its subsidiaries. - - - - Visit the Qt website - - Licensed under the terms of the GNU General Public License, version 3. Please visit the GitHub page for source code and build instructions. @@ -2561,11 +2517,115 @@ Please try again. - nymea is a registered trademark of chargebyte GmbH. + nymea is a registered trademark of chargebyte austria GmbH. - Licensed under the terms of the nymea commercial license. + chargebyte GmbH + + + + Visit the nymea project website + + + + Open Source Licenses + + + + Qt core module + + + + Qt gui module + + + + Qt network module + + + + Qt QML module + + + + Qt Quick module + + + + Qt Quick Controls module + + + + Qt Quick Dialogs module + + + + Qt Quick Layouts module + + + + Qt 5 compatibility module + + + + Qt image formats module + + + + Qt SVG module + + + + Qt charts module + + + + Qt websockets module + + + + Qt bluetooth module + + + + Qt NFC module + + + + Client library for remote connections + + + + QtZeroConf library by Jonathan Bagg + + + + Firebase iOS SDK + + + + Firebase Android SDK + + + + OpenSSL libraries by Eric Young + + + + Suru icons by Ubuntu + + + + Ubuntu font by Ubuntu + + + + Oswald font by The Oswald Project + + + + Google fonts and material icons diff --git a/nymea-app/translations/nymea-app.en_US.ts b/nymea-app/translations/nymea-app.en_US.ts index bda262d5..86a816b3 100644 --- a/nymea-app/translations/nymea-app.en_US.ts +++ b/nymea-app/translations/nymea-app.en_US.ts @@ -104,34 +104,6 @@ App version: - - Qt version: - - - - Built with %1 - - - - Suru icons by Ubuntu - - - - Ubuntu font by Ubuntu - - - - QtZeroConf library by Jonathan Bagg - - - - OpenSSL libraries by Eric Young - - - - Oswald font by The Oswald Project - - ActionLogPage @@ -588,10 +560,6 @@ Telegram - - Discord - - ConfigureThingPage @@ -2528,10 +2496,6 @@ Please try again. Howdy cowboy! - - Visit the nymea website - - Visit GitHub page @@ -2540,14 +2504,6 @@ Please try again. View privacy policy - - Qt is a registered trademark of The Qt Company Ltd. and its subsidiaries. - - - - Visit the Qt website - - Licensed under the terms of the GNU General Public License, version 3. Please visit the GitHub page for source code and build instructions. @@ -2561,11 +2517,115 @@ Please try again. - nymea is a registered trademark of chargebyte GmbH. + nymea is a registered trademark of chargebyte austria GmbH. - Licensed under the terms of the nymea commercial license. + chargebyte GmbH + + + + Visit the nymea project website + + + + Open Source Licenses + + + + Qt core module + + + + Qt gui module + + + + Qt network module + + + + Qt QML module + + + + Qt Quick module + + + + Qt Quick Controls module + + + + Qt Quick Dialogs module + + + + Qt Quick Layouts module + + + + Qt 5 compatibility module + + + + Qt image formats module + + + + Qt SVG module + + + + Qt charts module + + + + Qt websockets module + + + + Qt bluetooth module + + + + Qt NFC module + + + + Client library for remote connections + + + + QtZeroConf library by Jonathan Bagg + + + + Firebase iOS SDK + + + + Firebase Android SDK + + + + OpenSSL libraries by Eric Young + + + + Suru icons by Ubuntu + + + + Ubuntu font by Ubuntu + + + + Oswald font by The Oswald Project + + + + Google fonts and material icons diff --git a/nymea-app/translations/nymea-app.it.ts b/nymea-app/translations/nymea-app.it.ts index 6480d5dd..7a3509a5 100644 --- a/nymea-app/translations/nymea-app.it.ts +++ b/nymea-app/translations/nymea-app.it.ts @@ -104,34 +104,6 @@ App version: Versione app: - - Qt version: - Versione Qt: - - - Built with %1 - - - - Suru icons by Ubuntu - Icone Suru di Ubuntu - - - Ubuntu font by Ubuntu - Font Ubuntu di Ubuntu - - - QtZeroConf library by Jonathan Bagg - Libreria QtZeroConf di Jonathan Bagg - - - OpenSSL libraries by Eric Young - Libreria OpenSSL di Eric Young - - - Oswald font by The Oswald Project - Font Oswald di The Oswald Project - ActionLogPage @@ -588,10 +560,6 @@ Telegram - - Discord - - ConfigureThingPage @@ -2528,10 +2496,6 @@ Please try again. Howdy cowboy! - - Visit the nymea website - - Visit GitHub page @@ -2540,14 +2504,6 @@ Please try again. View privacy policy - - Qt is a registered trademark of The Qt Company Ltd. and its subsidiaries. - - - - Visit the Qt website - - Licensed under the terms of the GNU General Public License, version 3. Please visit the GitHub page for source code and build instructions. @@ -2561,11 +2517,115 @@ Please try again. - nymea is a registered trademark of chargebyte GmbH. + nymea is a registered trademark of chargebyte austria GmbH. - Licensed under the terms of the nymea commercial license. + chargebyte GmbH + + + + Visit the nymea project website + + + + Open Source Licenses + + + + Qt core module + + + + Qt gui module + + + + Qt network module + + + + Qt QML module + + + + Qt Quick module + + + + Qt Quick Controls module + + + + Qt Quick Dialogs module + + + + Qt Quick Layouts module + + + + Qt 5 compatibility module + + + + Qt image formats module + + + + Qt SVG module + + + + Qt charts module + + + + Qt websockets module + + + + Qt bluetooth module + + + + Qt NFC module + + + + Client library for remote connections + + + + QtZeroConf library by Jonathan Bagg + Libreria QtZeroConf di Jonathan Bagg + + + Firebase iOS SDK + + + + Firebase Android SDK + + + + OpenSSL libraries by Eric Young + Libreria OpenSSL di Eric Young + + + Suru icons by Ubuntu + Icone Suru di Ubuntu + + + Ubuntu font by Ubuntu + Font Ubuntu di Ubuntu + + + Oswald font by The Oswald Project + Font Oswald di The Oswald Project + + + Google fonts and material icons diff --git a/nymea-app/translations/nymea-app.ko.ts b/nymea-app/translations/nymea-app.ko.ts index ed811e80..a0561d5c 100644 --- a/nymea-app/translations/nymea-app.ko.ts +++ b/nymea-app/translations/nymea-app.ko.ts @@ -104,34 +104,6 @@ App version: App 버전: - - Qt version: - Qt 버전: - - - Built with %1 - - - - Suru icons by Ubuntu - - - - Ubuntu font by Ubuntu - - - - QtZeroConf library by Jonathan Bagg - - - - OpenSSL libraries by Eric Young - - - - Oswald font by The Oswald Project - - ActionLogPage @@ -587,10 +559,6 @@ Telegram - - Discord - - ConfigureThingPage @@ -2524,10 +2492,6 @@ Please try again. Howdy cowboy! 카우보이! - - Visit the nymea website - nymea 웹 사이트 방문 - Visit GitHub page GitHub 페이지 방문 @@ -2536,14 +2500,6 @@ Please try again. View privacy policy 개인 정보 보호 정책 보기 - - Qt is a registered trademark of The Qt Company Ltd. and its subsidiaries. - Qt는 Qt사 및 자회사의 등록 상표입니다. - - - Visit the Qt website - Qt 웹 사이트 방문 - Licensed under the terms of the GNU General Public License, version 3. Please visit the GitHub page for source code and build instructions. @@ -2557,11 +2513,115 @@ Please try again. - nymea is a registered trademark of chargebyte GmbH. - nymea는 chargebyte GmbH 및 그 자회사의 등록 상표입니다. + nymea is a registered trademark of chargebyte austria GmbH. + - Licensed under the terms of the nymea commercial license. + chargebyte GmbH + + + + Visit the nymea project website + + + + Open Source Licenses + + + + Qt core module + + + + Qt gui module + + + + Qt network module + + + + Qt QML module + + + + Qt Quick module + + + + Qt Quick Controls module + + + + Qt Quick Dialogs module + + + + Qt Quick Layouts module + + + + Qt 5 compatibility module + + + + Qt image formats module + + + + Qt SVG module + + + + Qt charts module + + + + Qt websockets module + + + + Qt bluetooth module + + + + Qt NFC module + + + + Client library for remote connections + + + + QtZeroConf library by Jonathan Bagg + + + + Firebase iOS SDK + + + + Firebase Android SDK + + + + OpenSSL libraries by Eric Young + + + + Suru icons by Ubuntu + + + + Ubuntu font by Ubuntu + + + + Oswald font by The Oswald Project + + + + Google fonts and material icons diff --git a/nymea-app/translations/nymea-app.nl.ts b/nymea-app/translations/nymea-app.nl.ts index d7032be5..71c531e4 100644 --- a/nymea-app/translations/nymea-app.nl.ts +++ b/nymea-app/translations/nymea-app.nl.ts @@ -104,34 +104,6 @@ App version: App versie: - - Qt version: - - - - Built with %1 - Gebouwd met %1 - - - Suru icons by Ubuntu - Suru icons door Ubuntu - - - Ubuntu font by Ubuntu - - - - QtZeroConf library by Jonathan Bagg - QtZeroConf library door Jonathan Bagg - - - OpenSSL libraries by Eric Young - OpenSSL libraries door Eric Young - - - Oswald font by The Oswald Project - Oswald font door The Oswald Project - ActionLogPage @@ -588,10 +560,6 @@ Telegram Telegram - - Discord - Discord - ConfigureThingPage @@ -2537,10 +2505,6 @@ Probeer het nog een keer. Howdy cowboy! Hallo daar! - - Visit the nymea website - Bezoek de nymea website - Visit GitHub page Bezoek de GitHub pagina @@ -2549,14 +2513,6 @@ Probeer het nog een keer. View privacy policy Bekijk het privacybeleid - - Qt is a registered trademark of The Qt Company Ltd. and its subsidiaries. - Qt is een geregistreerd handelsmerk van The Qt Company Ltd. en haar dochterondernemingen. - - - Visit the Qt website - Bezoek de Qt website - Licensed under the terms of the GNU General Public License, version 3. Please visit the GitHub page for source code and build instructions. Gelicentieerd onder de voorwaarden van de GNU General Public License, versie 3. Bezoek de GitHub pagina voor de broncode en de build instructies. @@ -2570,11 +2526,115 @@ Probeer het nog een keer. Aanvullende software licenties - nymea is a registered trademark of chargebyte GmbH. - nymea is een geregistreerd handelsmerk van chargebyte GmbH. + nymea is a registered trademark of chargebyte austria GmbH. + - Licensed under the terms of the nymea commercial license. + chargebyte GmbH + + + + Visit the nymea project website + + + + Open Source Licenses + + + + Qt core module + + + + Qt gui module + + + + Qt network module + + + + Qt QML module + + + + Qt Quick module + + + + Qt Quick Controls module + + + + Qt Quick Dialogs module + + + + Qt Quick Layouts module + + + + Qt 5 compatibility module + + + + Qt image formats module + + + + Qt SVG module + + + + Qt charts module + + + + Qt websockets module + + + + Qt bluetooth module + + + + Qt NFC module + + + + Client library for remote connections + + + + QtZeroConf library by Jonathan Bagg + QtZeroConf library door Jonathan Bagg + + + Firebase iOS SDK + + + + Firebase Android SDK + + + + OpenSSL libraries by Eric Young + OpenSSL libraries door Eric Young + + + Suru icons by Ubuntu + Suru icons door Ubuntu + + + Ubuntu font by Ubuntu + + + + Oswald font by The Oswald Project + Oswald font door The Oswald Project + + + Google fonts and material icons diff --git a/nymea-app/translations/nymea-app.tr.ts b/nymea-app/translations/nymea-app.tr.ts index de8cd339..03a69600 100644 --- a/nymea-app/translations/nymea-app.tr.ts +++ b/nymea-app/translations/nymea-app.tr.ts @@ -104,34 +104,6 @@ App version: Uygulama versiyon: - - Qt version: - Qt versiyon: - - - Built with %1 - % 1 ile oluşturuldu - - - Suru icons by Ubuntu - Ubuntu'dan Suru simgeleri - - - Ubuntu font by Ubuntu - Ubuntu'dan Ubuntu yazı tipi - - - QtZeroConf library by Jonathan Bagg - QtZeroConf kütüphanesi, Jonathan Bagg - - - OpenSSL libraries by Eric Young - Eric Young tarafından OpenSSL kütüphaneleri - - - Oswald font by The Oswald Project - Oswald yazı tipi by The Oswald Project - ActionLogPage @@ -587,10 +559,6 @@ Telegram - - Discord - - ConfigureThingPage @@ -2523,10 +2491,6 @@ Please try again. Howdy cowboy! Merhaba kovboy! - - Visit the nymea website - nymea'nin web sitesini ziyaret edin - Visit GitHub page GitHub sayfasını ziyaret edin @@ -2535,14 +2499,6 @@ Please try again. View privacy policy Gizlilik politikasını görüntüle - - Qt is a registered trademark of The Qt Company Ltd. and its subsidiaries. - Qt, The Qt Company Ltd. ve yan kuruluşlarının tescilli ticari markasıdır. - - - Visit the Qt website - Qt'nin web sitesini ziyaret edin - Licensed under the terms of the GNU General Public License, version 3. Please visit the GitHub page for source code and build instructions. GNU Genel Kamu Lisansı, sürüm 3 koşulları altında lisanslanmıştır. Kaynak kodu ve yapım talimatları için lütfen GitHub sayfasını ziyaret edin. @@ -2556,11 +2512,115 @@ Please try again. Ek yazılım lisansları - nymea is a registered trademark of chargebyte GmbH. - nymea, chargebyte GmbH.nin tescilli ticari markasıdır. + nymea is a registered trademark of chargebyte austria GmbH. + - Licensed under the terms of the nymea commercial license. + chargebyte GmbH + + + + Visit the nymea project website + + + + Open Source Licenses + + + + Qt core module + + + + Qt gui module + + + + Qt network module + + + + Qt QML module + + + + Qt Quick module + + + + Qt Quick Controls module + + + + Qt Quick Dialogs module + + + + Qt Quick Layouts module + + + + Qt 5 compatibility module + + + + Qt image formats module + + + + Qt SVG module + + + + Qt charts module + + + + Qt websockets module + + + + Qt bluetooth module + + + + Qt NFC module + + + + Client library for remote connections + + + + QtZeroConf library by Jonathan Bagg + QtZeroConf kütüphanesi, Jonathan Bagg + + + Firebase iOS SDK + + + + Firebase Android SDK + + + + OpenSSL libraries by Eric Young + Eric Young tarafından OpenSSL kütüphaneleri + + + Suru icons by Ubuntu + Ubuntu'dan Suru simgeleri + + + Ubuntu font by Ubuntu + Ubuntu'dan Ubuntu yazı tipi + + + Oswald font by The Oswald Project + Oswald yazı tipi by The Oswald Project + + + Google fonts and material icons diff --git a/nymea-app/translations/nymea-app.vi.ts b/nymea-app/translations/nymea-app.vi.ts index 0c7e130f..bf320f79 100644 --- a/nymea-app/translations/nymea-app.vi.ts +++ b/nymea-app/translations/nymea-app.vi.ts @@ -104,34 +104,6 @@ App version: - - Qt version: - - - - Built with %1 - - - - Suru icons by Ubuntu - - - - Ubuntu font by Ubuntu - - - - QtZeroConf library by Jonathan Bagg - - - - OpenSSL libraries by Eric Young - - - - Oswald font by The Oswald Project - - ActionLogPage @@ -587,10 +559,6 @@ Telegram - - Discord - - ConfigureThingPage @@ -2520,10 +2488,6 @@ Please try again. Howdy cowboy! - - Visit the nymea website - - Visit GitHub page @@ -2532,14 +2496,6 @@ Please try again. View privacy policy - - Qt is a registered trademark of The Qt Company Ltd. and its subsidiaries. - - - - Visit the Qt website - - Licensed under the terms of the GNU General Public License, version 3. Please visit the GitHub page for source code and build instructions. @@ -2553,11 +2509,115 @@ Please try again. - nymea is a registered trademark of chargebyte GmbH. + nymea is a registered trademark of chargebyte austria GmbH. - Licensed under the terms of the nymea commercial license. + chargebyte GmbH + + + + Visit the nymea project website + + + + Open Source Licenses + + + + Qt core module + + + + Qt gui module + + + + Qt network module + + + + Qt QML module + + + + Qt Quick module + + + + Qt Quick Controls module + + + + Qt Quick Dialogs module + + + + Qt Quick Layouts module + + + + Qt 5 compatibility module + + + + Qt image formats module + + + + Qt SVG module + + + + Qt charts module + + + + Qt websockets module + + + + Qt bluetooth module + + + + Qt NFC module + + + + Client library for remote connections + + + + QtZeroConf library by Jonathan Bagg + + + + Firebase iOS SDK + + + + Firebase Android SDK + + + + OpenSSL libraries by Eric Young + + + + Suru icons by Ubuntu + + + + Ubuntu font by Ubuntu + + + + Oswald font by The Oswald Project + + + + Google fonts and material icons diff --git a/nymea-app/ui/customviews/GenericTypeGraph.qml b/nymea-app/ui/customviews/GenericTypeGraph.qml index d1f61773..78e42f0e 100644 --- a/nymea-app/ui/customviews/GenericTypeGraph.qml +++ b/nymea-app/ui/customviews/GenericTypeGraph.qml @@ -405,7 +405,7 @@ Item { mainSeries.markClosestPoint(pt) } - onWheel: { + onWheel: (wheel) => { scrollRightLimited(-wheel.pixelDelta.x) // zoomInLimited(wheel.pixelDelta.y) } diff --git a/nymea-app/ui/customviews/MultiStateChart.qml b/nymea-app/ui/customviews/MultiStateChart.qml index 2a499c51..d21a6a99 100644 --- a/nymea-app/ui/customviews/MultiStateChart.qml +++ b/nymea-app/ui/customviews/MultiStateChart.qml @@ -241,7 +241,7 @@ Item { property double minValue property double maxValue - onBusyChanged: { + onBusyChanged: (busy) => { if (busy) { chartView.busyCounter++ } else { @@ -545,7 +545,7 @@ Item { d.now = new Date(Math.min(new Date(), new Date(startDatetime.getTime() + timeDelta))) } - onWheel: { + onWheel: (wheel) => { startDatetime = d.now var totalTime = d.endTime.getTime() - d.startTime.getTime() // pixelDelta : timeDelta = width : totalTime diff --git a/nymea-app/ui/customviews/StateChart.qml b/nymea-app/ui/customviews/StateChart.qml index b88bb3d3..6034a715 100644 --- a/nymea-app/ui/customviews/StateChart.qml +++ b/nymea-app/ui/customviews/StateChart.qml @@ -484,7 +484,7 @@ Item { d.now = new Date(Math.min(new Date(), new Date(startDatetime.getTime() + timeDelta))) } - onWheel: { + onWheel: (wheel) => { startDatetime = d.now var totalTime = d.endTime.getTime() - d.startTime.getTime() // pixelDelta : timeDelta = width : totalTime diff --git a/nymea-app/ui/mainviews/EnergyView.qml b/nymea-app/ui/mainviews/EnergyView.qml index 7978797d..438b2732 100644 --- a/nymea-app/ui/mainviews/EnergyView.qml +++ b/nymea-app/ui/mainviews/EnergyView.qml @@ -138,7 +138,6 @@ MainViewBase { consumers: consumers animationsEnabled: Qt.application.active && root.isCurrentItem && flickable.contentY < y + height && flickable.contentY + flickable.height > y onAnimationsEnabledChanged: print("animations for consumer balance chart", animationsEnabled ? "enabled" : "disabled") - } ConsumersHistory { diff --git a/nymea-app/ui/mainviews/airconditioning/ACChartsPage.qml b/nymea-app/ui/mainviews/airconditioning/ACChartsPage.qml index 94d410b7..c4d56a96 100644 --- a/nymea-app/ui/mainviews/airconditioning/ACChartsPage.qml +++ b/nymea-app/ui/mainviews/airconditioning/ACChartsPage.qml @@ -340,7 +340,7 @@ Page { startTime: new Date(d.startTime.getTime() - d.range * 60000) endTime: new Date(d.endTime.getTime() + d.range * 60000) sampleRate: d.sampleRate - onBusyChanged: { + onBusyChanged: (busy) => { if (busy) { chartView.busyCounter++ } else { @@ -348,17 +348,17 @@ Page { } } - onEntriesAddedIdx: { + onEntriesAddedIdx: (index, count) => { for (var i = 0; i < count; i++) { var entry = logsModel.get(i) var value = entry.values["temperature"] - if (value == null) { + if (value === null) { value = 0; } series.insert(index + i, entry.timestamp, value) } } - onEntriesRemoved: { + onEntriesRemoved: (index, count) => { series.removePoints(index, count) } Component.onCompleted: fetchLogs() @@ -397,7 +397,7 @@ Page { startTime: new Date(d.startTime.getTime() - d.range * 60000) endTime: new Date(d.endTime.getTime() + d.range * 60000) sampleRate: d.sampleRate - onBusyChanged: { + onBusyChanged: (busy) => { if (busy) { chartView.busyCounter++ } else { @@ -405,7 +405,7 @@ Page { } } - onEntriesAddedIdx: { + onEntriesAddedIdx: (index, count) => { for (var i = 0; i < count; i++) { var entry = logsModel.get(i) var value = entry.values["temperature"] @@ -415,7 +415,7 @@ Page { series.insert(index + i, entry.timestamp, value) } } - onEntriesRemoved: { + onEntriesRemoved: (index, count) => { series.removePoints(index, count) } Component.onCompleted: fetchLogs() @@ -455,7 +455,7 @@ Page { startTime: new Date(d.startTime.getTime() - d.range * 60000) endTime: new Date(d.endTime.getTime() + d.range * 60000) sampleRate: d.sampleRate - onBusyChanged: { + onBusyChanged: (busy) => { if (busy) { chartView.busyCounter++ } else { @@ -463,7 +463,7 @@ Page { } } - onEntriesAddedIdx: { + onEntriesAddedIdx: (index, count) => { for (var i = 0; i < count; i++) { var entry = logsModel.get(i) var value = entry.values["humidity"] @@ -473,7 +473,7 @@ Page { series.insert(index + i, entry.timestamp, value) } } - onEntriesRemoved: { + onEntriesRemoved: (index, count) => { series.removePoints(index, count) } Component.onCompleted: fetchLogs() @@ -509,14 +509,14 @@ Page { startTime: new Date(d.startTime.getTime() - d.range * 60000) endTime: new Date(d.endTime.getTime() + d.range * 60000) sampleRate: d.sampleRate - onBusyChanged: { + onBusyChanged: (busy) => { if (busy) { chartView.busyCounter++ } else { chartView.busyCounter-- } } - onEntriesAddedIdx: { + onEntriesAddedIdx: (index, count) => { for (var i = 0; i < count; i++) { var entry = logsModel.get(i) var value = entry.values["voc"] @@ -526,7 +526,7 @@ Page { series.insert(index + i, entry.timestamp, value) } } - onEntriesRemoved: { + onEntriesRemoved: (index, count) => { series.removePoints(index, count) } Component.onCompleted: fetchLogs() @@ -598,18 +598,18 @@ Page { startTime: new Date(d.startTime.getTime() - d.range * 60000) endTime: new Date(d.endTime.getTime() + d.range * 60000) property bool haveGeneratedLast: false - onBusyChanged: { + onBusyChanged: (busy) => { if (busy) { chartView.busyCounter++ } else { chartView.busyCounter-- } } - onEntriesAddedIdx: { + onEntriesAddedIdx: (index, count) => { for (var i = 0; i < count; i++) { var entry = logsModel.get(i) var value = entry.values["closed"] - if (value == null) { + if (value === null) { value = false; } @@ -627,7 +627,7 @@ Page { haveGeneratedLast = true } } - onEntriesRemoved: { + onEntriesRemoved: (index, count) => { closableUpperSeries.removePoints(index * 2, count * 2) if (haveGeneratedLast) { closableUpperSeries.removePoints(series.count - 1, 1) @@ -674,9 +674,9 @@ Page { XYPoint {x: dateTimeAxis.min.getTime(); y: 0} XYPoint {x: dateTimeAxis.max.getTime(); y: 0} function ensureValue(timestamp) { - if (count == 0) { + if (count === 0) { append(timestamp, 0) - } else if (count == 1) { + } else if (count === 1) { if (timestamp.getTime() < at(0).x) { insert(0, timestamp, 0) } else { @@ -708,18 +708,18 @@ Page { startTime: new Date(d.startTime.getTime() - d.range * 60000) endTime: new Date(d.endTime.getTime() + d.range * 60000) property bool haveGeneratedLast: false - onBusyChanged: { + onBusyChanged: (busy) => { if (busy) { chartView.busyCounter++ } else { chartView.busyCounter-- } } - onEntriesAddedIdx: { + onEntriesAddedIdx: (index, count) => { for (var i = 0; i < count; i++) { var entry = logsModel.get(i) var value = entry.values["heatingOn"] - if (value == null) { + if (value === null) { value = false; } @@ -738,7 +738,7 @@ Page { haveGeneratedLast = true } } - onEntriesRemoved: { + onEntriesRemoved: (index, count) => { heatingUpperSeries.removePoints(index * 2, count * 2) if (haveGeneratedLast) { heatingUpperSeries.removePoints(series.count - 1, 1) @@ -836,7 +836,7 @@ Page { d.now = new Date(Math.min(new Date(), new Date(startDatetime.getTime() + timeDelta))) } - onWheel: { + onWheel: (wheel) => { startDatetime = d.now var totalTime = d.endTime.getTime() - d.startTime.getTime() // pixelDelta : timeDelta = width : totalTime diff --git a/nymea-app/ui/mainviews/energy/CurrentPowerBalancePage.qml b/nymea-app/ui/mainviews/energy/CurrentPowerBalancePage.qml index e308954a..9941179c 100644 --- a/nymea-app/ui/mainviews/energy/CurrentPowerBalancePage.qml +++ b/nymea-app/ui/mainviews/energy/CurrentPowerBalancePage.qml @@ -50,14 +50,14 @@ Page { Layout.fillWidth: true Layout.fillHeight: true energyManager: root.energyManager - visible: root.producers.count > 0 + visible: root.producers ? root.producers.count > 0 : false animationsEnabled: Qt.application.active } CurrentProductionBalancePieChart { Layout.fillWidth: true Layout.fillHeight: true energyManager: root.energyManager - visible: root.producers.count > 0 + visible: root.producers ? root.producers.count > 0 : false animationsEnabled: Qt.application.active } } diff --git a/nymea-app/ui/system/zigbee/ZigbeeNetworkTopologyPage.qml b/nymea-app/ui/system/zigbee/ZigbeeNetworkTopologyPage.qml index 75802073..6576adf0 100644 --- a/nymea-app/ui/system/zigbee/ZigbeeNetworkTopologyPage.qml +++ b/nymea-app/ui/system/zigbee/ZigbeeNetworkTopologyPage.qml @@ -501,7 +501,7 @@ Page { canvas.requestPaint(); } - onWheel: { + onWheel: (wheel) => { if (wheel.modifiers & Qt.ControlModifier) { root.scale = Math.min(root.maxScale, Math.max(root.minScale, root.scale + 1.0 * wheel.angleDelta.y / 1000)) root.reload() diff --git a/version.txt b/version.txt index e5877f29..1f879bc4 100644 --- a/version.txt +++ b/version.txt @@ -1,2 +1,2 @@ 1.11.0 -679 +680 From dcbe619fc148d93911167cb526d9f6e5ebdf8f8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Fri, 28 Nov 2025 12:00:14 +0100 Subject: [PATCH 23/50] Make lrelease work on all platforms --- nymea-app.pro | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/nymea-app.pro b/nymea-app.pro index e1e53824..f133be61 100644 --- a/nymea-app.pro +++ b/nymea-app.pro @@ -116,6 +116,10 @@ TRANSLATIONS += $$files($$absolute_path(nymea-app)/translations/*.ts, true) include($${OVERLAY_PATH}/translations.pri) } -system("lrelease $$TRANSLATIONS") -lrelease.commands = lrelease $$TRANSLATIONS +message("Translation files: $$TRANSLATIONS") + +qtPrepareTool(LRELEASE, lrelease) + +system("$$LRELEASE $$TRANSLATIONS") +lrelease.commands = $$LRELEASE $$TRANSLATIONS QMAKE_EXTRA_TARGETS += lrelease From ce952dc536e893ded00cf93f3a9f0f20909ab374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 1 Dec 2025 09:59:35 +0100 Subject: [PATCH 24/50] android: Fix empty name on some app launchers --- packaging/android/AndroidManifest.xml | 10 +++------- packaging/android/res/values/strings.xml | 4 ++++ 2 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 packaging/android/res/values/strings.xml diff --git a/packaging/android/AndroidManifest.xml b/packaging/android/AndroidManifest.xml index e242d9ea..6141ef4d 100644 --- a/packaging/android/AndroidManifest.xml +++ b/packaging/android/AndroidManifest.xml @@ -25,7 +25,7 @@ @@ -67,11 +67,7 @@ android:launchMode="singleTop" android:screenOrientation="unspecified" android:exported="true" - android:label=""> - - - - + android:label="@string/app_name"> diff --git a/packaging/android/res/values/strings.xml b/packaging/android/res/values/strings.xml new file mode 100644 index 00000000..0a8e0018 --- /dev/null +++ b/packaging/android/res/values/strings.xml @@ -0,0 +1,4 @@ + + + nymea:app + From 009e69c456bba3bb35c39b93e0f290bde6233b68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 1 Dec 2025 09:59:56 +0100 Subject: [PATCH 25/50] Add app revision for the about screen --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 1f879bc4..a7a42a18 100644 --- a/version.txt +++ b/version.txt @@ -1,2 +1,2 @@ 1.11.0 -680 +681 From 8f6ed7c8a078e89484f4a115514b78ff45d4dd8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 1 Dec 2025 10:18:25 +0100 Subject: [PATCH 26/50] android: Fix vibrate --- .../android/platformhelperandroid.cpp | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/nymea-app/platformintegration/android/platformhelperandroid.cpp b/nymea-app/platformintegration/android/platformhelperandroid.cpp index 342c2d97..125b0c8d 100644 --- a/nymea-app/platformintegration/android/platformhelperandroid.cpp +++ b/nymea-app/platformintegration/android/platformhelperandroid.cpp @@ -145,7 +145,7 @@ QString PlatformHelperAndroid::deviceManufacturer() const void PlatformHelperAndroid::vibrate(PlatformHelper::HapticsFeedback feedbackType) { - int duration; + jlong duration; switch (feedbackType) { case HapticsFeedbackSelection: duration = 10; @@ -164,13 +164,28 @@ void PlatformHelperAndroid::vibrate(PlatformHelper::HapticsFeedback feedbackType return; } - QJniObject vibrator = context.callMethod("getSystemService", "Landroid/content/Context;Ljava/lang/String;", QJniObject::fromString("vibrator").object()); + QJniObject vibrator = context.callObjectMethod("getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;", QJniObject::fromString("vibrator").object()); if (!vibrator.isValid()) { qDebug() << "Could not get vibrator service."; return; } - // Call the vibrate method + const jint sdkInt = QJniObject::getStaticField("android/os/Build$VERSION", "SDK_INT"); + if (sdkInt >= 26) { + const jint defaultAmplitude = QJniObject::getStaticField("android/os/VibrationEffect", "DEFAULT_AMPLITUDE"); + QJniObject vibrationEffect = QJniObject::callStaticObjectMethod("android/os/VibrationEffect", + "createOneShot", + "(JI)Landroid/os/VibrationEffect;", + duration, + defaultAmplitude); + if (vibrationEffect.isValid()) { + vibrator.callMethod("vibrate", "(Landroid/os/VibrationEffect;)V", vibrationEffect.object()); + return; + } + qDebug() << "Falling back to legacy vibrate API, vibration effect invalid."; + } + + // Fallback for pre-API 26 or if creating the vibration effect failed vibrator.callMethod("vibrate", "(J)V", duration); } From 48bed7bf3e383b77254d4fa7085cd5477e9de942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 1 Dec 2025 12:47:29 +0100 Subject: [PATCH 27/50] Android: Fix push notifications and permission handling --- .../nymeaapp/NymeaAppNotificationService.java | 63 ++++++++++++++++--- .../android/platformpermissionsandroid.cpp | 53 +++++++++++++++- .../platformpermissions.cpp | 10 +-- nymea-app/pushnotifications.cpp | 9 ++- packaging/android/AndroidManifest.xml | 1 + packaging/android/res/values/strings.xml | 2 + 6 files changed, 121 insertions(+), 17 deletions(-) diff --git a/nymea-app/platformintegration/android/java-firebase/io/guh/nymeaapp/NymeaAppNotificationService.java b/nymea-app/platformintegration/android/java-firebase/io/guh/nymeaapp/NymeaAppNotificationService.java index 10daf500..2682c200 100644 --- a/nymea-app/platformintegration/android/java-firebase/io/guh/nymeaapp/NymeaAppNotificationService.java +++ b/nymea-app/platformintegration/android/java-firebase/io/guh/nymeaapp/NymeaAppNotificationService.java @@ -26,6 +26,8 @@ import java.util.Random; public class NymeaAppNotificationService extends FirebaseMessagingService { private static final String TAG = "nymea-app: NymeaAppNotificationService"; + private static final String DEFAULT_CHANNEL_ID = "default-channel"; + private static final String DEFAULT_CHANNEL_NAME = "nymea notifications"; private int hashId(String id) { int hash = 7; @@ -59,13 +61,28 @@ public class NymeaAppNotificationService extends FirebaseMessagingService { super.onMessageReceived(remoteMessage); + RemoteMessage.Notification notification = remoteMessage.getNotification(); + String title = notification != null ? notification.getTitle() : null; + String body = notification != null ? notification.getBody() : null; + if (title == null) { + title = remoteMessage.getData().get("title"); + } + if (body == null) { + body = remoteMessage.getData().get("body"); + } + Log.d(TAG, "Notification from: " + remoteMessage.getFrom()); - Log.d(TAG, "Notification title: " + remoteMessage.getNotification().getTitle()); - Log.d(TAG, "Notification body: " + remoteMessage.getNotification().getBody()); + Log.d(TAG, "Notification title: " + title); + Log.d(TAG, "Notification body: " + body); Log.d(TAG, "Notification priority: " + remoteMessage.getPriority()); Log.d(TAG, "Notification data: " + remoteMessage.getData()); Log.d(TAG, "Notification message ID: " + remoteMessage.getMessageId()); + if (title == null && body == null && remoteMessage.getData().isEmpty()) { + Log.w(TAG, "No notification payload received, skipping notification creation."); + return; + } + Intent intent = new Intent(this, NymeaAppActivity.class); //intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.setAction(Intent.ACTION_SEND); @@ -79,21 +96,36 @@ public class NymeaAppNotificationService extends FirebaseMessagingService { // Because of this, we need to dynamically fetch the resource from the package resources int resId = getResources().getIdentifier("notificationicon", "drawable", getPackageName()); Log.d(TAG, "Notification icon resource: " + resId + " Package:" + getPackageName()); + if (resId == 0) { + resId = getApplicationInfo().icon; + Log.w(TAG, "Notification icon resource missing, using application icon: " + resId); + } NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + if (notificationManager == null) { + Log.w(TAG, "NotificationManager not available, cannot display notification."); + return; + } + + String channelId = resolveStringResource("notification_channel_id", DEFAULT_CHANNEL_ID); + String channelName = resolveStringResource("notification_channel_name", DEFAULT_CHANNEL_NAME); // Since android Oreo notification channel is needed. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - NotificationChannel channel = new NotificationChannel("default-channel", "Default notification channel for nymea-app", NotificationManager.IMPORTANCE_HIGH); - notificationManager.createNotificationChannel(channel); + NotificationChannel existingChannel = notificationManager.getNotificationChannel(channelId); + if (existingChannel == null) { + NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH); + notificationManager.createNotificationChannel(channel); + } } - NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) - .setContentTitle(remoteMessage.getNotification().getTitle()) - .setContentText(remoteMessage.getNotification().getBody()) + NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId) + .setContentTitle(title) + .setContentText(body) .setSmallIcon(resId) .setAutoCancel(true) - .setContentIntent(pendingIntent); + .setContentIntent(pendingIntent) + .setPriority(NotificationCompat.PRIORITY_HIGH); boolean sound = remoteMessage.getData().get("sound") == null || remoteMessage.getData().get("sound").equals("true"); Log.d(TAG, "Notification sound enabled: " + (sound ? "true" : "false")); @@ -114,4 +146,19 @@ public class NymeaAppNotificationService extends FirebaseMessagingService { Log.d(TAG, "Posting Notification: " + remoteMessage.getMessageId()); notificationManager.notify(0, notificationBuilder.build()); } + + private String resolveStringResource(String resourceName, String fallback) { + int resId = getResources().getIdentifier(resourceName, "string", getPackageName()); + if (resId != 0) { + try { + String resolved = getString(resId); + if (resolved != null && !resolved.isEmpty()) { + return resolved; + } + } catch (Resources.NotFoundException e) { + Log.w(TAG, "String resource not found for " + resourceName + ", using fallback"); + } + } + return fallback; + } } diff --git a/nymea-app/platformintegration/android/platformpermissionsandroid.cpp b/nymea-app/platformintegration/android/platformpermissionsandroid.cpp index 213942a1..1dbdaad7 100644 --- a/nymea-app/platformintegration/android/platformpermissionsandroid.cpp +++ b/nymea-app/platformintegration/android/platformpermissionsandroid.cpp @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include "logging.h" NYMEA_LOGGING_CATEGORY(dcPlatformPermissions, "PlatformPermissions") @@ -108,8 +110,30 @@ PlatformPermissions::PermissionStatus PlatformPermissionsAndroid::checkPermissio }); break; } + break; } case PlatformPermissions::PermissionNotifications: { + if (QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::Android, 13)) { + status = PermissionStatusGranted; + break; + } + + auto futureResult = QtAndroidPrivate::checkPermission("android.permission.POST_NOTIFICATIONS"); + QtAndroidPrivate::PermissionResult result = futureResult.result(); + switch (result) { + case QtAndroidPrivate::Authorized: + qCDebug(dcPlatformPermissions()) << "Notifications permission already granted."; + status = PermissionStatusGranted; + break; + case QtAndroidPrivate::Denied: + qCDebug(dcPlatformPermissions()) << "Notifications permission denied."; + status = PermissionStatusDenied; + break; + case QtAndroidPrivate::Undetermined: + qCDebug(dcPlatformPermissions()) << "Notifications permission not yet requested. Requesting..."; + status = PermissionStatusNotDetermined; + break; + } break; } default: @@ -154,8 +178,7 @@ void PlatformPermissionsAndroid::requestPermission(PlatformPermissions::Permissi } case PlatformPermissions::PermissionLocalNetwork: { QFuture permission_request = QtAndroidPrivate::requestPermission("android.permission.POST_NOTIFICATIONS"); - switch(permission_request.result()) - { + switch(permission_request.result()) { case QtAndroidPrivate::Undetermined: qWarning() << "Permission for posting notifications undetermined!"; break; @@ -169,6 +192,31 @@ void PlatformPermissionsAndroid::requestPermission(PlatformPermissions::Permissi break; } + case PlatformPermissions::PermissionNotifications: { + if (QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::Android, 13)) { + qCDebug(dcPlatformPermissions()) << "Notifications permission implicitly granted on Android < 13."; + emit s_instance->notificationsPermissionChanged(); + break; + } + + QFuture permission_request = QtAndroidPrivate::requestPermission("android.permission.POST_NOTIFICATIONS"); + auto result = permission_request.result(); + switch(result) { + case QtAndroidPrivate::Undetermined: + qWarning() << "Permission for posting notifications undetermined!"; + s_instance->m_requestedButDeniedPermissions.append(platformPermission); + break; + case QtAndroidPrivate::Authorized: + qDebug() << "Permission for posting notifications authorized"; + break; + case QtAndroidPrivate::Denied: + qWarning() << "Permission for posting notifications denied!"; + s_instance->m_requestedButDeniedPermissions.append(platformPermission); + break; + } + emit s_instance->notificationsPermissionChanged(); + break; + } default: qCWarning(dcPlatformPermissions()) << "Requested platform permission" << platformPermission << "but is not implemented yet."; break; @@ -276,4 +324,3 @@ void PlatformPermissionsAndroid::requestPermission(PlatformPermissions::Permissi // emit s_instance->backgroundLocationPermissionChanged(); // emit s_instance->notificationsPermissionChanged(); // } - diff --git a/nymea-app/platformintegration/platformpermissions.cpp b/nymea-app/platformintegration/platformpermissions.cpp index b6ba1ae5..178fa914 100644 --- a/nymea-app/platformintegration/platformpermissions.cpp +++ b/nymea-app/platformintegration/platformpermissions.cpp @@ -33,11 +33,14 @@ PlatformPermissions *PlatformPermissions::instance() { #ifdef Q_OS_ANDROID - return new PlatformPermissionsAndroid(); + static PlatformPermissionsAndroid instance; + return &instance; #elif defined Q_OS_IOS - return new PlatformPermissionsIOS(); + static PlatformPermissionsIOS instance; + return &instance; #else - return new PlatformPermissions(); + static PlatformPermissions instance; + return &instance; #endif } @@ -85,4 +88,3 @@ PlatformPermissions::PermissionStatus PlatformPermissions::checkPermission(Permi Q_UNUSED(permission) return PermissionStatusGranted; } - diff --git a/nymea-app/pushnotifications.cpp b/nymea-app/pushnotifications.cpp index 3e5ca749..03b5489e 100644 --- a/nymea-app/pushnotifications.cpp +++ b/nymea-app/pushnotifications.cpp @@ -24,6 +24,7 @@ #include "pushnotifications.h" #include "platformhelper.h" +#include "platformintegration/platformpermissions.h" #include #include @@ -86,6 +87,9 @@ void PushNotifications::setEnabled(bool enabled) void PushNotifications::registerForPush() { #if defined Q_OS_ANDROID && defined WITH_FIREBASE + // Ensure we have runtime permission to post notifications (Android 13+). + PlatformPermissions::instance()->requestPermission(PlatformPermissions::PermissionNotifications); + qDebug() << "Checking for play services"; jboolean playServicesAvailable = QJniObject::callStaticMethod("io.guh.nymeaapp.NymeaAppNotificationService", "checkPlayServices", "()Z"); if (playServicesAvailable) { @@ -102,8 +106,9 @@ void PushNotifications::registerForPush() firebase::messaging::Initialize(*m_firebaseApp, this); firebase::messaging::SetListener(this); - // (Optional, Android 13+): Benachrichtigungs-Erlaubnis anfragen - // firebase::messaging::RequestPermission(); + // Android 13+ requires the POST_NOTIFICATIONS runtime permission. Request it here so + // Firebase is allowed to show notifications when the app is backgrounded or closed. + firebase::messaging::RequestPermission(); diff --git a/packaging/android/AndroidManifest.xml b/packaging/android/AndroidManifest.xml index 6141ef4d..abd50216 100644 --- a/packaging/android/AndroidManifest.xml +++ b/packaging/android/AndroidManifest.xml @@ -89,6 +89,7 @@ + diff --git a/packaging/android/res/values/strings.xml b/packaging/android/res/values/strings.xml index 0a8e0018..a4c0a262 100644 --- a/packaging/android/res/values/strings.xml +++ b/packaging/android/res/values/strings.xml @@ -1,4 +1,6 @@ nymea:app + default-channel + nymea notifications From 4cb037b51890ebb2f8ff3db0b3cc681c6afb6a4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 1 Dec 2025 15:33:17 +0100 Subject: [PATCH 28/50] Fix notification requests on android --- nymea-app/pushnotifications.cpp | 34 +++++---------------------------- 1 file changed, 5 insertions(+), 29 deletions(-) diff --git a/nymea-app/pushnotifications.cpp b/nymea-app/pushnotifications.cpp index 03b5489e..7797c6b4 100644 --- a/nymea-app/pushnotifications.cpp +++ b/nymea-app/pushnotifications.cpp @@ -87,8 +87,11 @@ void PushNotifications::setEnabled(bool enabled) void PushNotifications::registerForPush() { #if defined Q_OS_ANDROID && defined WITH_FIREBASE - // Ensure we have runtime permission to post notifications (Android 13+). - PlatformPermissions::instance()->requestPermission(PlatformPermissions::PermissionNotifications); + // Only proceed if notifications permission is granted (Android 13+). + if (PlatformPermissions::instance()->notificationsPermission() != PlatformPermissions::PermissionStatusGranted) { + qDebug() << "Notifications permission not granted yet, skipping Firebase registration."; + return; + } qDebug() << "Checking for play services"; jboolean playServicesAvailable = QJniObject::callStaticMethod("io.guh.nymeaapp.NymeaAppNotificationService", "checkPlayServices", "()Z"); @@ -109,33 +112,6 @@ void PushNotifications::registerForPush() // Android 13+ requires the POST_NOTIFICATIONS runtime permission. Request it here so // Firebase is allowed to show notifications when the app is backgrounded or closed. firebase::messaging::RequestPermission(); - - - - // // Activity + JNIEnv besorgen - // JNIEnv* env = QNativeInterface::QAndroidApplication::jniEnv(); - // jobject activity = QNativeInterface::QAndroidApplication::context(); - - // // Firebase App erstellen - // m_firebaseApp = firebase::App::Create(firebase::AppOptions(), env, activity); - - // // Messaging initialisieren und Listener setzen - // auto initResult = firebase::messaging::Initialize(*m_firebaseApp); - // if (initResult != firebase::kFutureStatusComplete) { - // // optional: warten oder loggen - // } - // firebase::messaging::SetListener(this); - - // // Optional: Token anfordern (wird i.d.R. via OnTokenReceived geliefert) - // firebase::messaging::RequestPermission(); // Android 13+ für Notifications sinnvoll - - - - - // m_firebaseApp = ::firebase::App::Create(::firebase::AppOptions(), QAndroidJniEnvironment(), QtAndroid::androidActivity().object()); - // m_firebase_initializer.Initialize(m_firebaseApp, nullptr, [](::firebase::App * fapp, void *) { - // return ::firebase::messaging::Initialize( *fapp, (::firebase::messaging::Listener *)m_client_pointer); - // }); } else { qDebug() << "Google Play Services not available. Cannot connect to push client."; } From 7eea6bd2c0b6ad23088c7c729fc5eed44b401170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 1 Dec 2025 15:33:23 +0100 Subject: [PATCH 29/50] Clean up notification handler on destruction to prevent shutdown crash --- libnymea-app/jsonrpc/jsonrpcclient.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libnymea-app/jsonrpc/jsonrpcclient.cpp b/libnymea-app/jsonrpc/jsonrpcclient.cpp index f106056a..76e15985 100644 --- a/libnymea-app/jsonrpc/jsonrpcclient.cpp +++ b/libnymea-app/jsonrpc/jsonrpcclient.cpp @@ -76,6 +76,17 @@ void JsonRpcClient::registerNotificationHandler(QObject *handler, const QString } m_notificationHandlers.insert(nameSpace, handler); m_notificationHandlerMethods.insert(handler, method); + + // Clean up if the handler gets destroyed so we don't dereference dangling pointers when + // processing notifications. + connect(handler, &QObject::destroyed, this, [this](QObject *obj){ + for (const QString &ns : m_notificationHandlers.keys(obj)) { + m_notificationHandlers.remove(ns, obj); + } + m_notificationHandlerMethods.remove(obj); + setNotificationsEnabled(); + }); + setNotificationsEnabled(); } From 1e3171a379112bb686a5b60eef6601ac6ca4dbb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 2 Dec 2025 09:31:51 +0100 Subject: [PATCH 30/50] Improve iOS machine hostname in case it returns only localhost --- .../ios/platformhelperios.cpp | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/nymea-app/platformintegration/ios/platformhelperios.cpp b/nymea-app/platformintegration/ios/platformhelperios.cpp index abbd28b0..5b6b7d0a 100644 --- a/nymea-app/platformintegration/ios/platformhelperios.cpp +++ b/nymea-app/platformintegration/ios/platformhelperios.cpp @@ -30,6 +30,7 @@ #include #include #include +#include PlatformHelperIOS::PlatformHelperIOS(QObject *parent) : PlatformHelper(parent) { @@ -61,7 +62,21 @@ void PlatformHelperIOS::hideSplashScreen() QString PlatformHelperIOS::machineHostname() const { - return QSysInfo::machineHostName(); + const QString hostName = QSysInfo::machineHostName(); + if (!hostName.isEmpty() && hostName != "localhost") { + return hostName; + } + + // Fall back to something user visible when the OS only reports "localhost". + const QString model = deviceModel(); + const QString manufacturer = deviceManufacturer(); + if (model.isEmpty()) { + return manufacturer; + } + if (manufacturer.isEmpty() || model.startsWith(manufacturer)) { + return model; + } + return manufacturer + " " + model; } QString PlatformHelperIOS::device() const @@ -87,6 +102,14 @@ QString PlatformHelperIOS::deviceSerial() const QString PlatformHelperIOS::deviceModel() const { + struct utsname systemInfo; + if (uname(&systemInfo) == 0) { + const QString machine = QString::fromUtf8(systemInfo.machine); + if (!machine.isEmpty()) { + return machine; + } + } + return QSysInfo::prettyProductName(); } From 5948a704d235be8f5347f3d270103b59f3b2402a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 2 Dec 2025 12:29:37 +0100 Subject: [PATCH 31/50] Fix nullptr tag call Fix iOS background color --- libnymea-app/tagsmanager.cpp | 1 - nymea-app/ui/Nymea.qml | 14 ++++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/libnymea-app/tagsmanager.cpp b/libnymea-app/tagsmanager.cpp index 00131d7d..3835f734 100644 --- a/libnymea-app/tagsmanager.cpp +++ b/libnymea-app/tagsmanager.cpp @@ -190,7 +190,6 @@ Tag* TagsManager::unpackTag(const QVariantMap &tagMap) tag->setRuleId(ruleId); } else { qCWarning(dcTags()) << "Invalid tag. Neither thingId nor ruleId are set. Skipping..."; - tag->deleteLater(); return nullptr; } // qDebug() << "adding tag" << tag->tagId() << tag->value(); diff --git a/nymea-app/ui/Nymea.qml b/nymea-app/ui/Nymea.qml index 49b80522..a370e168 100644 --- a/nymea-app/ui/Nymea.qml +++ b/nymea-app/ui/Nymea.qml @@ -54,6 +54,18 @@ ApplicationWindow { font.capitalization: Font.MixedCase font.family: Style.fontFamily + Binding { + target: PlatformHelper + property: "topPanelColor" + value: app.color + } + + Binding { + target: PlatformHelper + property: "bottomPanelColor" + value: app.color + } + property int margins: 16 property int bigMargins: 20 @@ -85,8 +97,6 @@ ApplicationWindow { Component.onCompleted: { styleController.setSystemFont(app.font) - PlatformHelper.topPanelColor = Style.backgroundColor - PlatformHelper.bottomPanelColor = Style.backgroundColor } Binding { From f4e8361d9d325e220a70badf0e8ad64265f55abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 2 Dec 2025 16:30:50 +0100 Subject: [PATCH 32/50] Update ssl lib for android --- 3rdParty/android/android_openssl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdParty/android/android_openssl b/3rdParty/android/android_openssl index ef412c6e..32ebe304 160000 --- a/3rdParty/android/android_openssl +++ b/3rdParty/android/android_openssl @@ -1 +1 @@ -Subproject commit ef412c6ebf131fae29a873d0c5db6c6b9dd494fd +Subproject commit 32ebe304ff064a9affb699b2185af78e3494f49a From b1f161bb3a0285dc18da8782091748127de3914e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 2 Dec 2025 16:31:24 +0100 Subject: [PATCH 33/50] debian: Switch debian packaging to Qt6 android: Fix android manifest --- packaging/android/AndroidManifest.xml | 1 - packaging/ubuntu/debian-qt6/compat | 2 +- packaging/ubuntu/debian-qt6/control | 23 +++++++---------------- packaging/ubuntu/debian-qt6/rules | 7 ++++--- version.txt | 2 +- 5 files changed, 13 insertions(+), 22 deletions(-) diff --git a/packaging/android/AndroidManifest.xml b/packaging/android/AndroidManifest.xml index abd50216..6141ef4d 100644 --- a/packaging/android/AndroidManifest.xml +++ b/packaging/android/AndroidManifest.xml @@ -89,7 +89,6 @@ - diff --git a/packaging/ubuntu/debian-qt6/compat b/packaging/ubuntu/debian-qt6/compat index ec635144..b1bd38b6 100644 --- a/packaging/ubuntu/debian-qt6/compat +++ b/packaging/ubuntu/debian-qt6/compat @@ -1 +1 @@ -9 +13 diff --git a/packaging/ubuntu/debian-qt6/control b/packaging/ubuntu/debian-qt6/control index e897e970..e44c14d6 100644 --- a/packaging/ubuntu/debian-qt6/control +++ b/packaging/ubuntu/debian-qt6/control @@ -9,15 +9,19 @@ Build-Depends: debhelper, dpkg-dev, libavahi-client-dev, libavahi-common-dev, + libxkbcommon-dev, qt6-base-dev, qt6-base-dev-tools, + qt6-base-private-dev, qt6-connectivity-dev, qt6-charts-dev, qt6-svg-dev, qt6-websockets-dev, qt6-webview-dev, qt6-declarative-dev, - libqt6quickcontrols2-6, + qt6-tools-dev, + libqt6quickcontrols2-6 + Package: nymea-app Architecture: any @@ -25,21 +29,8 @@ Section: x11 Multi-Arch: same Depends: ${shlibs:Depends}, ${misc:Depends}, - libqt5network5, - libqt5gui5, - libqt5websockets5, - libqt5bluetooth5, - qml-module-qt-labs-calendar, - qml-module-qt-labs-folderlistmodel, - qml-module-qt-labs-settings, - qml-module-qtcharts, - qml-module-qtgraphicaleffects, - qml-module-qtquick-controls2, - qml-module-qtquick-layouts, - qml-module-qtquick-window2, - qml-module-qtquick2, -Recommends: qml-module-qtwebview, -Suggests: nymea, +Recommends: qml6-module-qtwebview, +Suggests: nymea, network-manager Description: A client app for nymea This package will install nymea:app, the client app diff --git a/packaging/ubuntu/debian-qt6/rules b/packaging/ubuntu/debian-qt6/rules index 71262a39..87e05cff 100755 --- a/packaging/ubuntu/debian-qt6/rules +++ b/packaging/ubuntu/debian-qt6/rules @@ -3,8 +3,9 @@ export DH_VERBOSE=1 -override_dh_missing: - dh_missing --fail-missing +override_dh_auto_install: + dh_auto_install --destdir=debian/tmp %: - dh $@ --buildsystem=qmake --parallel --with systemd + dh $@ --buildsystem=qmake6 --parallel + diff --git a/version.txt b/version.txt index a7a42a18..f73b60e9 100644 --- a/version.txt +++ b/version.txt @@ -1,2 +1,2 @@ 1.11.0 -681 +682 From 9e76717487a6094769f9f5c3361aca1d5a2d5c15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 3 Dec 2025 21:40:21 +0100 Subject: [PATCH 34/50] Bump version --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index f73b60e9..a40b8885 100644 --- a/version.txt +++ b/version.txt @@ -1,2 +1,2 @@ 1.11.0 -682 +683 From dec89523be34f0d582593e5ebfb3f91c70f19c34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Thu, 4 Dec 2025 15:26:47 +0100 Subject: [PATCH 35/50] Update permission instance handling and update android manifest permissions --- nymea-app/platformintegration/platformpermissions.cpp | 9 +++------ packaging/android/AndroidManifest.xml | 3 +++ version.txt | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/nymea-app/platformintegration/platformpermissions.cpp b/nymea-app/platformintegration/platformpermissions.cpp index 178fa914..246c3b04 100644 --- a/nymea-app/platformintegration/platformpermissions.cpp +++ b/nymea-app/platformintegration/platformpermissions.cpp @@ -33,14 +33,11 @@ PlatformPermissions *PlatformPermissions::instance() { #ifdef Q_OS_ANDROID - static PlatformPermissionsAndroid instance; - return &instance; + return new PlatformPermissionsAndroid(); #elif defined Q_OS_IOS - static PlatformPermissionsIOS instance; - return &instance; + return new PlatformPermissionsIOS(); #else - static PlatformPermissions instance; - return &instance; + return new PlatformPermissions(); #endif } diff --git a/packaging/android/AndroidManifest.xml b/packaging/android/AndroidManifest.xml index 6141ef4d..79c49837 100644 --- a/packaging/android/AndroidManifest.xml +++ b/packaging/android/AndroidManifest.xml @@ -11,6 +11,8 @@ + + @@ -89,6 +91,7 @@ + diff --git a/version.txt b/version.txt index a40b8885..31599850 100644 --- a/version.txt +++ b/version.txt @@ -1,2 +1,2 @@ 1.11.0 -683 +686 From 590063aa195d00431d4467ac62fb002215b1cc59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Thu, 4 Dec 2025 21:46:40 +0100 Subject: [PATCH 36/50] Fix android permissions --- .../android/platformpermissionsandroid.cpp | 260 ++++++++---------- .../platformpermissions.cpp | 9 +- 2 files changed, 123 insertions(+), 146 deletions(-) diff --git a/nymea-app/platformintegration/android/platformpermissionsandroid.cpp b/nymea-app/platformintegration/android/platformpermissionsandroid.cpp index 1dbdaad7..d8f1e5dd 100644 --- a/nymea-app/platformintegration/android/platformpermissionsandroid.cpp +++ b/nymea-app/platformintegration/android/platformpermissionsandroid.cpp @@ -26,6 +26,8 @@ #include #include +#include +#include #include #include #include @@ -64,15 +66,16 @@ PlatformPermissions::PermissionStatus PlatformPermissionsAndroid::checkPermissio case PlatformPermissions::PermissionBluetooth: { QBluetoothPermission permission; - // Status prüfen - auto status = qApp->checkPermission(permission); + const auto permissionStatus = qApp->checkPermission(permission); - switch (status) { + switch (permissionStatus) { case Qt::PermissionStatus::Granted: qCDebug(dcPlatformPermissions()) << "Bluetooth permission already granted."; + status = PermissionStatusGranted; break; case Qt::PermissionStatus::Denied: qCDebug(dcPlatformPermissions()) << "Bluetooth permission denied."; + status = PermissionStatusDenied; break; case Qt::PermissionStatus::Undetermined: qCDebug(dcPlatformPermissions()) << "Bluetooth permission not yet requested. Requesting..."; @@ -82,32 +85,75 @@ PlatformPermissions::PermissionStatus PlatformPermissionsAndroid::checkPermissio else qCDebug(dcPlatformPermissions()) << "Bluetooth permission denied after request."; }); + status = PermissionStatusNotDetermined; break; } break; } case PlatformPermissions::PermissionLocalNetwork: { + if (QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::Android, 13)) { + status = PermissionStatusGranted; + break; + } + + const auto permissionResult = QtAndroidPrivate::checkPermission("android.permission.NEARBY_WIFI_DEVICES").result(); + switch (permissionResult) { + case QtAndroidPrivate::Authorized: + qCDebug(dcPlatformPermissions()) << "Local network permission already granted."; + status = PermissionStatusGranted; + break; + case QtAndroidPrivate::Denied: + qCDebug(dcPlatformPermissions()) << "Local network permission denied."; + status = PermissionStatusDenied; + break; + case QtAndroidPrivate::Undetermined: + qCDebug(dcPlatformPermissions()) << "Local network permission not yet requested."; + status = PermissionStatusNotDetermined; + break; + } + break; + } + case PlatformPermissions::PermissionLocation: { QLocationPermission permission; permission.setAccuracy(QLocationPermission::Precise); - // Status prüfen - auto status = qApp->checkPermission(permission); + const auto permissionStatus = qApp->checkPermission(permission); - switch (status) { + switch (permissionStatus) { case Qt::PermissionStatus::Granted: qCDebug(dcPlatformPermissions()) << "Location permission already granted."; + status = PermissionStatusGranted; break; case Qt::PermissionStatus::Denied: qCDebug(dcPlatformPermissions()) << "Location permission denied."; + status = PermissionStatusDenied; break; case Qt::PermissionStatus::Undetermined: - qCDebug(dcPlatformPermissions()) << "Location permission not yet requested. Requesting..."; - qApp->requestPermission(permission, [](const QPermission &perm){ - if (perm.status() == Qt::PermissionStatus::Granted) - qCDebug(dcPlatformPermissions()) << "Location permission granted after request."; - else - qCDebug(dcPlatformPermissions()) << "Location permission denied after request."; - }); + qCDebug(dcPlatformPermissions()) << "Location permission not yet requested."; + status = PermissionStatusNotDetermined; + break; + } + break; + } + case PlatformPermissions::PermissionBackgroundLocation: { + if (QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::Android, 10)) { + // No dedicated background permission; use foreground status instead. + return checkPermission(PermissionLocation); + } + + const auto permissionResult = QtAndroidPrivate::checkPermission("android.permission.ACCESS_BACKGROUND_LOCATION").result(); + switch (permissionResult) { + case QtAndroidPrivate::Authorized: + qCDebug(dcPlatformPermissions()) << "Background location permission already granted."; + status = PermissionStatusGranted; + break; + case QtAndroidPrivate::Denied: + qCDebug(dcPlatformPermissions()) << "Background location permission denied."; + status = PermissionStatusDenied; + break; + case QtAndroidPrivate::Undetermined: + qCDebug(dcPlatformPermissions()) << "Background location permission not yet requested."; + status = PermissionStatusNotDetermined; break; } break; @@ -148,7 +194,7 @@ void PlatformPermissionsAndroid::requestPermission(PlatformPermissions::Permissi switch (platformPermission) { case PlatformPermissions::PermissionBluetooth: qCDebug(dcPlatformPermissions()) << "Requesting bluetooth permission"; - qApp->requestPermission(QLocationPermission{}, [platformPermission](const QPermission &permission) { + qApp->requestPermission(QBluetoothPermission{}, [platformPermission](const QPermission &permission) { if (permission.status() == Qt::PermissionStatus::Denied) { qCWarning(dcPlatformPermissions()) << "Bluetooth permission denied."; s_instance->m_requestedButDeniedPermissions.append(platformPermission); @@ -176,20 +222,49 @@ void PlatformPermissionsAndroid::requestPermission(PlatformPermissions::Permissi }); break; } - case PlatformPermissions::PermissionLocalNetwork: { - QFuture permission_request = QtAndroidPrivate::requestPermission("android.permission.POST_NOTIFICATIONS"); - switch(permission_request.result()) { - case QtAndroidPrivate::Undetermined: - qWarning() << "Permission for posting notifications undetermined!"; - break; - case QtAndroidPrivate::Authorized: - qDebug() << "Permission for posting notifications authorized"; - break; - case QtAndroidPrivate::Denied: - qWarning() << "Permission for posting notifications denied!"; + case PlatformPermissions::PermissionBackgroundLocation: { + if (QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::Android, 10)) { + emit s_instance->backgroundLocationPermissionChanged(); break; } + auto permissionRequest = QtAndroidPrivate::requestPermission("android.permission.ACCESS_BACKGROUND_LOCATION"); + permissionRequest.then(qApp, [platformPermission](QtAndroidPrivate::PermissionResult result) { + switch(result) { + case QtAndroidPrivate::Undetermined: + qWarning() << "Permission for background location undetermined!"; + s_instance->m_requestedButDeniedPermissions.append(platformPermission); + break; + case QtAndroidPrivate::Authorized: + qDebug() << "Permission for background location authorized"; + break; + case QtAndroidPrivate::Denied: + qWarning() << "Permission for background location denied!"; + s_instance->m_requestedButDeniedPermissions.append(platformPermission); + break; + } + emit s_instance->backgroundLocationPermissionChanged(); + }); + break; + } + case PlatformPermissions::PermissionLocalNetwork: { + auto permissionRequest = QtAndroidPrivate::requestPermission("android.permission.NEARBY_WIFI_DEVICES"); + permissionRequest.then(qApp, [platformPermission](QtAndroidPrivate::PermissionResult result) { + switch(result) { + case QtAndroidPrivate::Undetermined: + qWarning() << "Permission for local network undetermined!"; + s_instance->m_requestedButDeniedPermissions.append(platformPermission); + break; + case QtAndroidPrivate::Authorized: + qDebug() << "Permission for local network authorized"; + break; + case QtAndroidPrivate::Denied: + qWarning() << "Permission for local network denied!"; + s_instance->m_requestedButDeniedPermissions.append(platformPermission); + break; + } + emit s_instance->localNetworkPermissionChanged(); + }); break; } case PlatformPermissions::PermissionNotifications: { @@ -199,128 +274,27 @@ void PlatformPermissionsAndroid::requestPermission(PlatformPermissions::Permissi break; } - QFuture permission_request = QtAndroidPrivate::requestPermission("android.permission.POST_NOTIFICATIONS"); - auto result = permission_request.result(); - switch(result) { - case QtAndroidPrivate::Undetermined: - qWarning() << "Permission for posting notifications undetermined!"; - s_instance->m_requestedButDeniedPermissions.append(platformPermission); - break; - case QtAndroidPrivate::Authorized: - qDebug() << "Permission for posting notifications authorized"; - break; - case QtAndroidPrivate::Denied: - qWarning() << "Permission for posting notifications denied!"; - s_instance->m_requestedButDeniedPermissions.append(platformPermission); - break; - } - emit s_instance->notificationsPermissionChanged(); + auto permissionRequest = QtAndroidPrivate::requestPermission("android.permission.POST_NOTIFICATIONS"); + permissionRequest.then(qApp, [platformPermission](QtAndroidPrivate::PermissionResult result) { + switch(result) { + case QtAndroidPrivate::Undetermined: + qWarning() << "Permission for posting notifications undetermined!"; + s_instance->m_requestedButDeniedPermissions.append(platformPermission); + break; + case QtAndroidPrivate::Authorized: + qDebug() << "Permission for posting notifications authorized"; + break; + case QtAndroidPrivate::Denied: + qWarning() << "Permission for posting notifications denied!"; + s_instance->m_requestedButDeniedPermissions.append(platformPermission); + break; + } + emit s_instance->notificationsPermissionChanged(); + }); break; } default: qCWarning(dcPlatformPermissions()) << "Requested platform permission" << platformPermission << "but is not implemented yet."; break; } - - emit s_instance->locationPermissionChanged(); - emit s_instance->backgroundLocationPermissionChanged(); - emit s_instance->notificationsPermissionChanged(); - - // if (permissionMap().contains(permission)) { - // qCDebug(dcPlatformPermissions()) << "Requesting permissions:" << permissionMap().value(permission); - - - - // qApp->requestPermission(QCameraPermission{}, [](const QPermission &permission) { - - - // if (permission.status() == Qt::PermissionStatus::Granted) - // takePhoto(); - // }); - - // // QtAndroid::requestPermissions({permissionMap().value(permission)}, &permissionResultCallback); - // } } - -// void PlatformPermissionsAndroid::openPermissionSettings() -// { -// qCDebug(dcPlatformPermissions()) << "Opening permission dialog."; -// QJniObject packageName = QtAndroid::androidContext().callObjectMethod("getPackageName", "()Ljava/lang/String;"); -// QString packageUri = "package:" + packageName.toString(); -// QJniObject uri = QJniObject::callStaticObjectMethod("android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", QJniObject::fromString(packageUri).object()); -// QAndroidIntent intent = QAndroidIntent("android.settings.APPLICATION_DETAILS_SETTINGS"); -// intent.handle().callObjectMethod("setData", "(Landroid/net/Uri;)Landroid/content/Intent;", uri.object()); -// intent.handle().callObjectMethod("addFlags", "(I)Landroid/content/Intent;", FLAG_ACTIVITY_NEW_TASK); -// QtAndroid::androidContext().callMethod("startActivity", "(Landroid/content/Intent;)V", intent.handle().object()); -// } - -// QHash PlatformPermissionsAndroid::permissionMap() const -// { -// QOperatingSystemVersion osVersion = QOperatingSystemVersion::current(); -// if (osVersion.majorVersion() <= 9) { -// return { -// {PlatformPermissions::PermissionBluetooth, {"android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}}, -// {PlatformPermissions::PermissionLocation, {"android.permission.ACCESS_FINE_LOCATION"}}, -// {PlatformPermissions::PermissionBackgroundLocation, {"android.permission.ACCESS_FINE_LOCATION"}} -// }; -// } -// if (osVersion.majorVersion() <= 10) { -// return { -// {PlatformPermissions::PermissionBluetooth, {"android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}}, -// {PlatformPermissions::PermissionLocation, {"android.permission.ACCESS_FINE_LOCATION"}}, -// {PlatformPermissions::PermissionBackgroundLocation, {"android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_BACKGROUND_LOCATION"}} -// }; -// } -// if (osVersion.majorVersion() <= 12) { -// return { -// // TODO: Once QtBluetooth does not request the COARSE_LOCATION and FINE_LOCATION for Bluetooth any more, remove it from here. The new Bluetooth permissions would be enough. -// {PlatformPermissions::PermissionBluetooth, {"android.permission.BLUETOOTH_SCAN", "android.permission.BLUETOOTH_CONNECT", "android.permission.BLUETOOTH_ADVERTISE", "android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}}, -// {PlatformPermissions::PermissionLocation, {"android.permission.ACCESS_FINE_LOCATION"}}, -// {PlatformPermissions::PermissionBackgroundLocation, {"android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_BACKGROUND_LOCATION"}} -// }; -// } -// return { -// // TODO: Once QtBluetooth does not request the COARSE_LOCATION and FINE_LOCATION for Bluetooth any more, remove it from here. The new Bluetooth permissions would be enough. -// {PlatformPermissions::PermissionBluetooth, {"android.permission.BLUETOOTH_SCAN", "android.permission.BLUETOOTH_CONNECT", "android.permission.BLUETOOTH_ADVERTISE", "android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}}, -// {PlatformPermissions::PermissionLocation, {"android.permission.ACCESS_FINE_LOCATION"}}, -// {PlatformPermissions::PermissionBackgroundLocation, {"android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_BACKGROUND_LOCATION"}}, -// {PlatformPermissions::PermissionNotifications, {"android.permission.POST_NOTIFICATIONS"}} -// }; -// } - -// PlatformPermissions::PermissionStatus PlatformPermissionsAndroid::checkPermission(Permission permission) const -// { -// PermissionStatus status = PermissionStatusGranted; -// QStringList androidPermissions = permissionMap().value(permission); -// qCDebug(dcPlatformPermissions()) << "Checking permission" << permission << "(" << androidPermissions << ")"; -// foreach (const QString androidPermission, androidPermissions) { -// if (QtAndroid::shouldShowRequestPermissionRationale(androidPermission) || m_requestedButDeniedPermissions.contains(androidPermission)) { -// qCDebug(dcPlatformPermissions()) << "Permission:" << androidPermission << "denied"; -// status = PermissionStatusDenied; -// } -// if (QtAndroid::checkPermission(androidPermission) == QtAndroid::PermissionResult::Denied) { -// qDebug(dcPlatformPermissions()) << "Permission:" << androidPermission << "not determined"; -// if (status != PermissionStatusDenied) { -// status = PermissionStatusNotDetermined; -// } -// } else { -// qDebug(dcPlatformPermissions()) << "Permission:" << androidPermission << "granted"; -// } -// } -// qCDebug(dcPlatformPermissions()) << "Permission status for:" << permission << ":" << status; -// return status; -// } - -// void PlatformPermissionsAndroid::permissionResultCallback(const QtAndroid::PermissionResultMap &results) -// { -// foreach (const QString &androidPermission, results.keys()) { -// qCDebug(dcPlatformPermissions()) << "Permission result callback:" << androidPermission << (results.value(androidPermission) == QtAndroid::PermissionResult::Granted ? "Granted" : "Denied"); -// if (results.value(androidPermission) == QtAndroid::PermissionResult::Denied) { -// s_instance->m_requestedButDeniedPermissions.append(androidPermission); -// } -// } -// emit s_instance->bluetoothPermissionChanged(); -// emit s_instance->locationPermissionChanged(); -// emit s_instance->backgroundLocationPermissionChanged(); -// emit s_instance->notificationsPermissionChanged(); -// } diff --git a/nymea-app/platformintegration/platformpermissions.cpp b/nymea-app/platformintegration/platformpermissions.cpp index 246c3b04..178fa914 100644 --- a/nymea-app/platformintegration/platformpermissions.cpp +++ b/nymea-app/platformintegration/platformpermissions.cpp @@ -33,11 +33,14 @@ PlatformPermissions *PlatformPermissions::instance() { #ifdef Q_OS_ANDROID - return new PlatformPermissionsAndroid(); + static PlatformPermissionsAndroid instance; + return &instance; #elif defined Q_OS_IOS - return new PlatformPermissionsIOS(); + static PlatformPermissionsIOS instance; + return &instance; #else - return new PlatformPermissions(); + static PlatformPermissions instance; + return &instance; #endif } From d3cb28ae15b2591052f05bd5169d63361efb7636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Thu, 4 Dec 2025 21:53:10 +0100 Subject: [PATCH 37/50] Bump version --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 31599850..1a8bcf31 100644 --- a/version.txt +++ b/version.txt @@ -1,2 +1,2 @@ 1.11.0 -686 +687 From 0f6584668828d257a23be0ea2f64c81b43ec1722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Fri, 5 Dec 2025 13:58:46 +0100 Subject: [PATCH 38/50] Update to 1.11.1 --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 1a8bcf31..82cfbbbb 100644 --- a/version.txt +++ b/version.txt @@ -1,2 +1,2 @@ -1.11.0 +1.11.1 687 From f44d75ae17af1f9d3e6bb0b83b68b9a51cda34d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Fri, 5 Dec 2025 14:14:19 +0100 Subject: [PATCH 39/50] windows: Update build flags --- nymea-app/nymea-app.pro | 13 +++++++++---- nymea-remoteproxy | 2 +- shared.pri | 13 ++++++++++--- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/nymea-app/nymea-app.pro b/nymea-app/nymea-app.pro index 9ef24745..a16746fa 100644 --- a/nymea-app/nymea-app.pro +++ b/nymea-app/nymea-app.pro @@ -17,10 +17,15 @@ INCLUDEPATH += $$top_srcdir/libnymea-app \ linux:!android: LIBS += -L$$top_builddir/libnymea-app/ -lnymea-app -L$$top_builddir/experiences/airconditioning -lnymea-app-airconditioning -win32:Debug:LIBS += -L$$top_builddir/libnymea-app/debug \ - -L$$top_builddir/experiences/airconditioning/debug -win32:Release:LIBS += -L$$top_builddir/libnymea-app/release \ - -L$$top_builddir/experiences/airconditioning/release +win32:Debug:LIBS += -L$$top_builddir/libnymea-app/debug -lnymea-app \ + -L$$top_builddir/experiences/airconditioning/debug -lnymea-app-airconditioning +win32:Release:LIBS += -L$$top_builddir/libnymea-app/release -lnymea-app \ + -L$$top_builddir/experiences/airconditioning/release -lnymea-app-airconditioning + +win32:Debug:PRE_TARGETDEPS += $$top_builddir/libnymea-app/debug/nymea-app.lib \ + $$top_builddir/experiences/airconditioning/debug/nymea-app-airconditioning.lib +win32:Release:PRE_TARGETDEPS += $$top_builddir/libnymea-app/release/nymea-app.lib \ + $$top_builddir/experiences/airconditioning/release/nymea-app-airconditioning.lib win32:CXX_FLAGS += /w linux:!android:!nozeroconf:LIBS += -lavahi-client -lavahi-common diff --git a/nymea-remoteproxy b/nymea-remoteproxy index c8997b52..b57d178b 160000 --- a/nymea-remoteproxy +++ b/nymea-remoteproxy @@ -1 +1 @@ -Subproject commit c8997b5260d665f7b3fe988d42bdf5d4ce434f4c +Subproject commit b57d178bf33ca647798b4ff02d63869b2b15fa4d diff --git a/shared.pri b/shared.pri index 8b5e8981..75396d09 100644 --- a/shared.pri +++ b/shared.pri @@ -11,7 +11,16 @@ greaterThan(QT_MAJOR_VERSION, 5) { DEFINES += QT_DISABLE_DEPRECATED_UP_TO=0x050F00 } -QMAKE_CXXFLAGS *= -Werror -g -Wno-deprecated-declarations +win32-msvc { + QMAKE_CXXFLAGS += /WX + QMAKE_CXXFLAGS += /wd4996 +} else { + QMAKE_CXXFLAGS += -Werror + QMAKE_CXXFLAGS += -Wno-deprecated-declarations + QMAKE_CXXFLAGS += -Wno-deprecated-copy +} + +QMAKE_CXXFLAGS += -g top_srcdir=$$PWD top_builddir=$$shadowed($$PWD) @@ -37,8 +46,6 @@ INCLUDEPATH += $${top_builddir} # On Windows, -Wall goes mental, so not using it there !win32:QMAKE_CXXFLAGS += -Wall -QMAKE_CXXFLAGS += -Wno-deprecated-declarations -Wno-deprecated-copy - android: { QMAKE_CXXFLAGS += -Wno-deprecated-declarations QMAKE_LFLAGS *= "-Wl,-z,max-page-size=16384" From ecea0eae2660e312d51ea9aae47618d3b3ae2367 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 9 Dec 2025 12:56:36 +0100 Subject: [PATCH 40/50] Set submodule nymea-remoteproxy back to master branch --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 6bbdd2fa..540bdea7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,7 +5,7 @@ [submodule "nymea-remoteproxy"] path = nymea-remoteproxy url = https://github.com/nymea/nymea-remoteproxy.git - branch = qt6-cmake + branch = master [submodule "android_openssl"] path = 3rdParty/android/android_openssl url = https://github.com/KDAB/android_openssl.git From e14137296e18cdf5ad05237429e2b329f3060781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 22 Oct 2025 14:01:14 +0200 Subject: [PATCH 41/50] Improve permission handling and add new Thing based permission basics --- libnymea-app/types/userinfo.h | 1 + libnymea-app/usermanager.h | 3 +- nymea-app/ui/system/UsersSettingsPage.qml | 78 ++++++++++++---- nymea-app/ui/utils/NymeaUtils.qml | 109 ++++++++++++++++++++-- 4 files changed, 162 insertions(+), 29 deletions(-) diff --git a/libnymea-app/types/userinfo.h b/libnymea-app/types/userinfo.h index 27b80a11..47fd6ca9 100644 --- a/libnymea-app/types/userinfo.h +++ b/libnymea-app/types/userinfo.h @@ -39,6 +39,7 @@ public: PermissionScopeNone = 0x0000, PermissionScopeControlThings = 0x0001, PermissionScopeConfigureThings = 0x0003, + PermissionScopeAccessAllThings = 0x0004, PermissionScopeExecuteRules = 0x0010, PermissionScopeConfigureRules = 0x0030, PermissionScopeAdmin = 0xFFFF, diff --git a/libnymea-app/usermanager.h b/libnymea-app/usermanager.h index 71a9cbda..f3c07d9e 100644 --- a/libnymea-app/usermanager.h +++ b/libnymea-app/usermanager.h @@ -53,7 +53,8 @@ public: UserErrorDuplicateUserId, UserErrorBadPassword, UserErrorTokenNotFound, - UserErrorPermissionDenied + UserErrorPermissionDenied, + UserErrorInconsistantScopes }; Q_ENUM(UserError) diff --git a/nymea-app/ui/system/UsersSettingsPage.qml b/nymea-app/ui/system/UsersSettingsPage.qml index 75988440..7bf8ecd0 100644 --- a/nymea-app/ui/system/UsersSettingsPage.qml +++ b/nymea-app/ui/system/UsersSettingsPage.qml @@ -323,6 +323,7 @@ SettingsPageBase { title: qsTr("Manage %1").arg(userInfo.username) property UserInfo userInfo: null + property bool restrictedThingAccess: userDetailsPage.userInfo.scopes & UserInfo.PermissionScopeAccessAllThings === 0 Component { id: confirmUserDeletionComponent @@ -382,30 +383,66 @@ SettingsPageBase { Repeater { model: NymeaUtils.scopesModel - delegate: CheckDelegate { - Layout.fillWidth: true - text: model.text - checked: (userDetailsPage.userInfo.scopes & model.scope) === model.scope + delegate: NymeaSwipeDelegate { - enabled: model.scope === UserInfo.PermissionScopeAdmin && userDetailsPage.userInfo.username == userManager.userInfo.username ? - false : model.scope === UserInfo.PermissionScopeAdmin || - ((userDetailsPage.userInfo.scopes & UserInfo.PermissionScopeAdmin) !== UserInfo.PermissionScopeAdmin) - onClicked: { - print("scopes:", userDetailsPage.userInfo.scopes) - var scopes = userDetailsPage.userInfo.scopes - if (checked) { - scopes |= model.scope - } else { - scopes &= ~model.scope - scopes |= model.resetOnUnset + Layout.fillWidth: true + + text: model.text + subText: model.description + progressive: false + + CheckBox { + anchors.right: parent.right + anchors.rightMargin: app.margins + anchors.verticalCenter: parent.verticalCenter + + checked: (userDetailsPage.userInfo.scopes & model.scope) === model.scope + enabled: { + // Prevent an admin to lock himself out as admin + if (model.scope === UserInfo.PermissionScopeAdmin && userDetailsPage.userInfo.username == userManager.userInfo.username) { + return false + } else { + return model.scope === UserInfo.PermissionScopeAdmin || ((userDetailsPage.userInfo.scopes & UserInfo.PermissionScopeAdmin) !== UserInfo.PermissionScopeAdmin) + } + } + + onClicked: { + var scopes = userDetailsPage.userInfo.scopes + if (checked) { + scopes |= model.scope + } else { + scopes &= ~model.scope + } + + // make sure the new permissions are consistant before sending them to the core + scopes = NymeaUtils.getPermissionScopeAdjustments(model.scope, checked, scopes) + userManager.setUserScopes(userDetailsPage.userInfo.username, scopes) } - print("username:", userDetailsPage.userInfo.username) - print("new scopes:", scopes, UserInfo.PermissionScopeAdmin) - userManager.setUserScopes(userDetailsPage.userInfo.username, scopes) } } } + + SettingsPageSectionHeader { + text: qsTr("Acessable things") + visible: userDetailsPage.restrictedThingAccess + Layout.fillWidth: true + } + + + NymeaSwipeDelegate { + id: allowedThingsEntry + Layout.fillWidth: true + text: qsTr("Allowed things for this user") + visible: userDetailsPage.restrictedThingAccess + progressive: true + onClicked: { + + } + + } + + SettingsPageSectionHeader { text: qsTr("Remove") } @@ -496,6 +533,7 @@ SettingsPageBase { text: qsTr("Permissions") } + Repeater { id: scopesRepeater model: NymeaUtils.scopesModel @@ -510,8 +548,10 @@ SettingsPageBase { scopes |= model.scope } else { scopes &= ~model.scope - scopes |= model.resetOnUnset } + + // make sure the new permissions are consistant before sending them to the core + scopes = NymeaUtils.getPermissionScopeAdjustments(model.scope, checked, scopes) createUserPage.permissionScopes = scopes } } diff --git a/nymea-app/ui/utils/NymeaUtils.qml b/nymea-app/ui/utils/NymeaUtils.qml index daec4ae7..b4c56ea1 100644 --- a/nymea-app/ui/utils/NymeaUtils.qml +++ b/nymea-app/ui/utils/NymeaUtils.qml @@ -32,7 +32,7 @@ Item { id: root function pad(num, size, base) { - if (base == undefined) { + if (base === undefined) { base = 10 } @@ -167,11 +167,102 @@ Item { } property ListModel scopesModel: ListModel { - ListElement { text: qsTr("Admin"); scope: UserInfo.PermissionScopeAdmin; resetOnUnset: UserInfo.PermissionScopeNone } - ListElement { text: qsTr("Control things"); scope: UserInfo.PermissionScopeControlThings; resetOnUnset: UserInfo.PermissionScopeNone } - ListElement { text: qsTr("Configure things"); scope: UserInfo.PermissionScopeConfigureThings; resetOnUnset: UserInfo.PermissionScopeControlThings } - ListElement { text: qsTr("Execute magic"); scope: UserInfo.PermissionScopeExecuteRules; resetOnUnset: UserInfo.PermissionScopeNone } - ListElement { text: qsTr("Configure magic"); scope: UserInfo.PermissionScopeConfigureRules; resetOnUnset: UserInfo.PermissionScopeExecuteRules } + ListElement { + text: qsTr("Admin") + description: qsTr("Full access to the system.") + scope: UserInfo.PermissionScopeAdmin + } + ListElement { + text: qsTr("Control things") + description: qsTr("Execute actions and use things and services.") + scope: UserInfo.PermissionScopeControlThings + } + ListElement { + text: qsTr("Configure things") + description: qsTr("Add new things and change settings.") + scope: UserInfo.PermissionScopeConfigureThings + } + ListElement { + text: qsTr("Access all things") + description: qsTr("Allow to see and use all things of the system.") + scope: UserInfo.PermissionScopeAccessAllThings + } + ListElement { + text: qsTr("Execute magic") + description: qsTr("Execute rules, scenes and scripts.") + scope: UserInfo.PermissionScopeExecuteRules + } + ListElement { + text: qsTr("Configure magic") + description: qsTr("Create new rules and scripts in the system.") + scope: UserInfo.PermissionScopeConfigureRules + } + } + + function getPermissionScopeAdjustments(scope, enabled, currentScopes) { + + var adjustedScopes = currentScopes; + + console.warn("Adjust permissions", scope, "->", enabled, currentScopes) + + if (enabled) { + + // Scope has been enabled + switch (scope) { + case UserInfo.PermissionScopeAdmin: + adjustedScopes = UserInfo.PermissionScopeAdmin + break; + case UserInfo.PermissionScopeControlThings: + break; + case UserInfo.PermissionScopeConfigureThings: + adjustedScopes |= UserInfo.PermissionScopeControlThings + adjustedScopes |= UserInfo.PermissionScopeAccessAllThings + break; + case UserInfo.PermissionScopeAccessAllThings: + adjustedScopes |= UserInfo.PermissionScopeControlThings + break; + case UserInfo.PermissionScopeExecuteRules: + adjustedScopes |= UserInfo.PermissionScopeAccessAllThings + break; + case UserInfo.PermissionScopeConfigureRules: + adjustedScopes |= UserInfo.PermissionScopeExecuteRules + adjustedScopes |= UserInfo.PermissionScopeAccessAllThings + break; + } + + } else { + + // Scope has been disabled + switch (scope) { + case UserInfo.PermissionScopeAdmin: + // Set the default permission for non admin + adjustedScopes = UserInfo.PermissionScopeAccessAllThings | UserInfo.PermissionScopeControlThings | UserInfo.PermissionScopeExecuteRules + break; + case UserInfo.PermissionScopeControlThings: + adjustedScopes &= ~UserInfo.PermissionScopeConfigureThings + break; + case UserInfo.PermissionScopeConfigureThings: + // Note: PermissionScopeConfigureThings is 3 and unsets therefore also the abbility to control things. + adjustedScopes |= UserInfo.PermissionScopeControlThings + break; + case UserInfo.PermissionScopeAccessAllThings: + adjustedScopes &= ~UserInfo.PermissionScopeConfigureThings + adjustedScopes &= ~UserInfo.PermissionScopeExecuteRules + adjustedScopes &= ~UserInfo.PermissionScopeConfigureRules + // Make sure we still can controll those things we added + adjustedScopes |= UserInfo.PermissionScopeControlThings + break; + case UserInfo.PermissionScopeExecuteRules: + adjustedScopes &= ~UserInfo.PermissionScopeConfigureRules + break; + case UserInfo.PermissionScopeConfigureRules: + // Note: PermissionScopeConfigureRules constand unsets therefore also the abbility to execute rules (screnes). + adjustedScopes |= UserInfo.PermissionScopeExecuteRules + break; + } + } + + return adjustedScopes } function hasPermissionScope(permissions, requestedScope) { @@ -201,9 +292,9 @@ Item { } function rgb2hsv(r,g,b) { - var v=Math.max(r,g,b), c=v-Math.min(r,g,b); - var h= c && ((v==r) ? (g-b)/c : ((v==g) ? 2+(b-r)/c : 4+(r-g)/c)); - return [60*(h<0?h+6:h), v&&c/v, v]; + var v=Math.max(r,g,b), c=v-Math.min(r,g,b); + var h= c && ((v===r) ? (g-b)/c : ((v===g) ? 2+(b-r)/c : 4+(r-g)/c)); + return [60*(h<0?h+6:h), v&&c/v, v]; } readonly property var sensorInterfaceStateMap: { From 0c574dff842268308903066c662856a9515767e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 27 Oct 2025 15:51:02 +0100 Subject: [PATCH 42/50] Add allowed thing configuration --- libnymea-app/types/userinfo.cpp | 33 +++++++++ libnymea-app/types/userinfo.h | 11 +++ libnymea-app/usermanager.cpp | 69 +++++++++++++++--- libnymea-app/usermanager.h | 13 ++-- nymea-app/ui/system/UsersSettingsPage.qml | 71 ++++++++++++++++--- .../thingconfiguration/ConfigureThingPage.qml | 34 +++++---- 6 files changed, 194 insertions(+), 37 deletions(-) diff --git a/libnymea-app/types/userinfo.cpp b/libnymea-app/types/userinfo.cpp index fb774ec6..3a677833 100644 --- a/libnymea-app/types/userinfo.cpp +++ b/libnymea-app/types/userinfo.cpp @@ -92,6 +92,39 @@ void UserInfo::setScopes(PermissionScopes scopes) } } +QList UserInfo::allowedThingIds() const +{ + return m_allowedThingIds; +} + +void UserInfo::setAllowedThingIds(const QList &allowedThingIds) +{ + if (m_allowedThingIds != allowedThingIds) { + m_allowedThingIds = allowedThingIds; + emit allowedThingIdsChanged(); + } +} + +bool UserInfo::thingAllowed(const QUuid &thingId) const +{ + return m_allowedThingIds.contains(thingId); +} + +void UserInfo::allowThingId(const QUuid &thingId, bool allowed) +{ + if (allowed) { + if (!m_allowedThingIds.contains(thingId)) { + m_allowedThingIds.append(thingId); + emit allowedThingIdsChanged(); + } + } else { + if (m_allowedThingIds.contains(thingId)) { + m_allowedThingIds.removeAll(thingId); + emit allowedThingIdsChanged(); + } + } +} + QStringList UserInfo::scopesToList(PermissionScopes scopes) { QStringList ret; diff --git a/libnymea-app/types/userinfo.h b/libnymea-app/types/userinfo.h index 47fd6ca9..5e180e51 100644 --- a/libnymea-app/types/userinfo.h +++ b/libnymea-app/types/userinfo.h @@ -25,6 +25,7 @@ #ifndef USERINFO_H #define USERINFO_H +#include #include class UserInfo : public QObject @@ -34,6 +35,8 @@ class UserInfo : public QObject Q_PROPERTY(QString email READ email NOTIFY emailChanged) Q_PROPERTY(QString displayName READ displayName NOTIFY displayNameChanged) Q_PROPERTY(PermissionScopes scopes READ scopes NOTIFY scopesChanged) + Q_PROPERTY(QList allowedThingIds READ allowedThingIds NOTIFY allowedThingIdsChanged) + public: enum PermissionScope { PermissionScopeNone = 0x0000, @@ -62,6 +65,12 @@ public: PermissionScopes scopes() const; void setScopes(PermissionScopes scopes); + QList allowedThingIds() const; + void setAllowedThingIds(const QList &allowedThingIds); + + Q_INVOKABLE bool thingAllowed(const QUuid &thingId) const; + Q_INVOKABLE void allowThingId(const QUuid &thingId, bool allowed); + static QStringList scopesToList(PermissionScopes scopes); static PermissionScopes listToScopes(const QStringList &scopeList); @@ -70,12 +79,14 @@ signals: void emailChanged(); void displayNameChanged(); void scopesChanged(); + void allowedThingIdsChanged(); private: QString m_username; QString m_email; QString m_displayName; PermissionScopes m_scopes = PermissionScopeNone; + QList m_allowedThingIds; }; diff --git a/libnymea-app/usermanager.cpp b/libnymea-app/usermanager.cpp index 9cd2a605..5cb403b5 100644 --- a/libnymea-app/usermanager.cpp +++ b/libnymea-app/usermanager.cpp @@ -67,6 +67,7 @@ void UserManager::setEngine(Engine *engine) m_loading = true; emit loadingChanged(); + m_engine->jsonRpcClient()->sendCommand("Users.GetUsers", QVariantMap(), this, "getUsersResponse"); m_engine->jsonRpcClient()->sendCommand("Users.GetUserInfo", QVariantMap(), this, "getUserInfoResponse"); m_engine->jsonRpcClient()->sendCommand("Users.GetTokens", QVariantMap(), this, "getTokensResponse"); @@ -94,8 +95,7 @@ Users *UserManager::users() const return m_users; } - -int UserManager::createUser(const QString &username, const QString &password, const QString &displayName, const QString &email, int permissionScopes) +int UserManager::createUser(const QString &username, const QString &password, const QString &displayName, const QString &email, int permissionScopes, const QList &allowedThingIds) { QVariantMap params; params.insert("username", username); @@ -105,7 +105,15 @@ int UserManager::createUser(const QString &username, const QString &password, co params.insert("email", email); params.insert("scopes", UserInfo::scopesToList((UserInfo::PermissionScopes)permissionScopes)); } - qCDebug(dcUserManager()) << "Creating user" << username << permissionScopes; + + if (m_engine->jsonRpcClient()->ensureServerVersion("8.4") && !allowedThingIds.isEmpty()) { + QVariantList thingIds; + foreach (const QUuid &thingId, allowedThingIds) + thingIds.append(thingId.toString()); + + params.insert("allowedThingIds", thingIds); + } + qCDebug(dcUserManager()) << "Creating user" << username << permissionScopes << allowedThingIds; return m_engine->jsonRpcClient()->sendCommand("Users.CreateUser", params, this, "createUserResponse"); } @@ -133,12 +141,19 @@ int UserManager::removeUser(const QString &username) return m_engine->jsonRpcClient()->sendCommand("Users.RemoveUser", params, this, "removeUserResponse"); } -int UserManager::setUserScopes(const QString &username, int scopes) +int UserManager::setUserScopes(const QString &username, int scopes, const QList &allowedThingIds) { QVariantMap params; params.insert("username", username); params.insert("scopes", UserInfo::scopesToList((UserInfo::PermissionScopes)scopes)); - qCDebug(dcUserManager()) << "Setting new permission scopes for user" << username << scopes << (int)scopes; + if (m_engine->jsonRpcClient()->ensureServerVersion("8.4") && !allowedThingIds.isEmpty()) { + QVariantList thingIds; + foreach (const QUuid &thingId, allowedThingIds) + thingIds.append(thingId); + + params.insert("allowedThingIds", thingIds); + } + qCDebug(dcUserManager()) << "Setting new permission scopes for user" << username << scopes << (int)scopes << allowedThingIds; return m_engine->jsonRpcClient()->sendCommand("Users.SetUserScopes", params, this, "setUserScopesResponse"); } @@ -162,6 +177,11 @@ void UserManager::notificationReceived(const QVariantMap &data) info->setDisplayName(userMap.value("displayName").toString()); info->setEmail(userMap.value("email").toString()); info->setScopes(UserInfo::listToScopes(userMap.value("scopes").toStringList())); + QList allowedThingIds; + foreach (const QString &thingIdString, userMap.value("allowedThingIds").toStringList()) + allowedThingIds.append(QUuid(thingIdString)); + + info->setAllowedThingIds(allowedThingIds); m_users->insertUser(info); } else if (notification == "Users.UserRemoved") { m_users->removeUser(data.value("params").toMap().value("username").toString()); @@ -171,11 +191,19 @@ void UserManager::notificationReceived(const QVariantMap &data) QString displayName = userMap.value("displayName").toString(); QString email = userMap.value("email").toString(); UserInfo::PermissionScopes scopes = UserInfo::listToScopes(userMap.value("scopes").toStringList()); + + QList allowedThingIds; + foreach (const QString &thingIdString, userMap.value("allowedThingIds").toStringList()) + allowedThingIds.append(QUuid(thingIdString)); + + // Update current user info if (m_userInfo && m_userInfo->username() == username) { m_userInfo->setDisplayName(displayName); m_userInfo->setEmail(email); m_userInfo->setScopes(scopes); + m_userInfo->setAllowedThingIds(allowedThingIds); + } // Update user info in the list of all users. UserInfo *info = m_users->getUserInfo(username); @@ -186,6 +214,7 @@ void UserManager::notificationReceived(const QVariantMap &data) info->setDisplayName(displayName); info->setEmail(email); info->setScopes(scopes); + info->setAllowedThingIds(allowedThingIds); } } @@ -195,10 +224,16 @@ void UserManager::getUsersResponse(int commandId, const QVariantMap &data) foreach (const QVariant &userVariant, data.value("users").toList()) { QVariantMap userMap = userVariant.toMap(); + + QList allowedThingIds; + foreach (const QString &thingIdString, userMap.value("allowedThingIds").toStringList()) + allowedThingIds.append(QUuid(thingIdString)); + UserInfo *userInfo = new UserInfo(userMap.value("username").toString()); userInfo->setDisplayName(userMap.value("displayName").toString()); userInfo->setEmail(userMap.value("email").toString()); userInfo->setScopes(UserInfo::listToScopes(userMap.value("scopes").toStringList())); + userInfo->setAllowedThingIds(allowedThingIds); m_users->insertUser(userInfo); } } @@ -207,15 +242,20 @@ void UserManager::getUserInfoResponse(int commandId, const QVariantMap &data) { qCDebug(dcUserManager()) << "User info reply" << commandId << data; QVariantMap userMap = data.value("userInfo").toMap(); + QList allowedThingIds; + foreach (const QString &thingIdString, userMap.value("allowedThingIds").toStringList()) + allowedThingIds.append(QUuid(thingIdString)); + m_userInfo->setUsername(userMap.value("username").toString()); m_userInfo->setEmail(userMap.value("email").toString()); m_userInfo->setDisplayName(userMap.value("displayName").toString()); m_userInfo->setScopes(UserInfo::listToScopes(userMap.value("scopes").toStringList())); + m_userInfo->setAllowedThingIds(allowedThingIds); } -void UserManager::getTokensResponse(int /*commandId*/, const QVariantMap &data) +void UserManager::getTokensResponse(int commandId, const QVariantMap &data) { - + Q_UNUSED(commandId) foreach (const QVariant &tokenVariant, data.value("tokenInfoList").toList()) { // qDebug() << "Token received" << tokenVariant.toMap(); QVariantMap token = tokenVariant.toMap(); @@ -226,7 +266,6 @@ void UserManager::getTokensResponse(int /*commandId*/, const QVariantMap &data) TokenInfo *tokenInfo = new TokenInfo(id, username, deviceName, creationTime); m_tokenInfos->addToken(tokenInfo); } - } void UserManager::removeTokenResponse(int commandId, const QVariantMap ¶ms) @@ -309,6 +348,13 @@ QVariant Users::data(const QModelIndex &index, int role) const return m_users.at(index.row())->email(); case RoleScopes: return static_cast(m_users.at(index.row())->scopes()); + case RoleAllowedThingIds: { + QVariantList thingIds; + foreach (const QUuid &thingId, m_users.at(index.row())->allowedThingIds()) + thingIds.append(thingId); + + return thingIds; + } } return QVariant(); } @@ -320,6 +366,7 @@ QHash Users::roleNames() const roles.insert(RoleDisplayName, "displayName"); roles.insert(RoleEmail, "email"); roles.insert(RoleScopes, "scopes"); + roles.insert(RoleAllowedThingIds, "allowedThingIds"); return roles; } @@ -344,6 +391,12 @@ void Users::insertUser(UserInfo *userInfo) emit dataChanged(index(idx), index(idx), {RoleScopes}); } }); + connect(userInfo, &UserInfo::allowedThingIdsChanged, this, [=](){ + int idx = m_users.indexOf(userInfo); + if (idx >= 0) { + emit dataChanged(index(idx), index(idx), {RoleAllowedThingIds}); + } + }); beginInsertRows(QModelIndex(), static_cast(m_users.count()), static_cast(m_users.count())); m_users.append(userInfo); diff --git a/libnymea-app/usermanager.h b/libnymea-app/usermanager.h index f3c07d9e..6935b5d9 100644 --- a/libnymea-app/usermanager.h +++ b/libnymea-app/usermanager.h @@ -71,12 +71,12 @@ public: Users *users() const; // NOTE: Q_FLAG from another QObject (UserInfo::PermissionScopes) doesn't seem to work in certain Qt versions. Using int instead - Q_INVOKABLE int createUser(const QString &username, const QString &password, const QString &displayName, const QString &email, int permissionScopes = UserInfo::PermissionScopeAdmin); + Q_INVOKABLE int createUser(const QString &username, const QString &password, const QString &displayName, const QString &email, int permissionScopes = UserInfo::PermissionScopeAdmin, const QList &allowedThingIds = QList()); Q_INVOKABLE int changePassword(const QString &newPassword); Q_INVOKABLE int removeToken(const QUuid &id); Q_INVOKABLE int removeUser(const QString &username); // NOTE: Q_FLAG from another QObject (UserInfo::PermissionScopes) doesn't seem to work in certain Qt versions. Using int instead - Q_INVOKABLE int setUserScopes(const QString &username, int permissionScopes); + Q_INVOKABLE int setUserScopes(const QString &username, int permissionScopes, const QList &allowedThingIds = QList()); Q_INVOKABLE int setUserInfo(const QString &username, const QString &displayName, const QString &email); signals: @@ -124,7 +124,8 @@ public: RoleUsername, RoleDisplayName, RoleEmail, - RoleScopes + RoleScopes, + RoleAllowedThingIds }; Q_ENUM(Roles) @@ -137,14 +138,14 @@ public: void insertUser(UserInfo *userInfo); void removeUser(const QString &username); - Q_INVOKABLE UserInfo* get(int index) const; - Q_INVOKABLE UserInfo* getUserInfo(const QString &username) const; + Q_INVOKABLE UserInfo *get(int index) const; + Q_INVOKABLE UserInfo *getUserInfo(const QString &username) const; signals: void countChanged(); private: - QList m_users; + QList m_users; }; #endif // USERMANAGER_H diff --git a/nymea-app/ui/system/UsersSettingsPage.qml b/nymea-app/ui/system/UsersSettingsPage.qml index 7bf8ecd0..17ccdabe 100644 --- a/nymea-app/ui/system/UsersSettingsPage.qml +++ b/nymea-app/ui/system/UsersSettingsPage.qml @@ -31,6 +31,7 @@ import Nymea import NymeaApp.Utils import "../components" +import "../delegates" SettingsPageBase { id: root @@ -138,6 +139,7 @@ SettingsPageBase { } } + Component { id: editUserInfoComponent SettingsPageBase { @@ -190,6 +192,59 @@ SettingsPageBase { } } + Component { + id: configureAllowedThingsComponent + + Page { + id: configureAllowedThingsPage + + property UserInfo userInfo: null + + header: NymeaHeader { + text: root.title + backButtonVisible: true + onBackPressed: pageStack.pop() + } + + title: qsTr("Allowed things for") + " \"" + userInfo.username + "\"" + ColumnLayout { + anchors.fill: parent + + ListFilterInput { + id: filterInput + Layout.fillWidth: true + } + + GroupedListView { + Layout.fillWidth: true + Layout.fillHeight: true + clip: true + + model: ThingsProxy { + id: thingsProxy + engine: _engine + groupByInterface: true + nameFilter: filterInput.shown ? filterInput.text : "" + } + + delegate: ThingDelegate { + id: thingDelegate + thing: thingsProxy.getThing(model.id) + canDelete: false + progressive: false + additionalItem: CheckBox { + checked: configureAllowedThingsPage.userInfo.thingAllowed(thingDelegate.thing.id) + onCheckedChanged: { + configureAllowedThingsPage.userInfo.allowThingId(thingDelegate.thing.id, checked) + userManager.setUserScopes(configureAllowedThingsPage.userInfo.username, configureAllowedThingsPage.userInfo.scopes, configureAllowedThingsPage.userInfo.allowedThingIds) + } + } + } + } + } + } + } + Component { id: changePasswordComponent SettingsPageBase { @@ -318,12 +373,12 @@ SettingsPageBase { Component { id: userDetailsComponent + SettingsPageBase { id: userDetailsPage title: qsTr("Manage %1").arg(userInfo.username) property UserInfo userInfo: null - property bool restrictedThingAccess: userDetailsPage.userInfo.scopes & UserInfo.PermissionScopeAccessAllThings === 0 Component { id: confirmUserDeletionComponent @@ -381,8 +436,9 @@ SettingsPageBase { } Repeater { - model: NymeaUtils.scopesModel + id: permissionRepeater + model: NymeaUtils.scopesModel delegate: NymeaSwipeDelegate { Layout.fillWidth: true @@ -416,7 +472,7 @@ SettingsPageBase { // make sure the new permissions are consistant before sending them to the core scopes = NymeaUtils.getPermissionScopeAdjustments(model.scope, checked, scopes) - userManager.setUserScopes(userDetailsPage.userInfo.username, scopes) + userManager.setUserScopes(userDetailsPage.userInfo.username, scopes, userDetailsPage.userInfo.allowedThingIds) } } } @@ -425,7 +481,7 @@ SettingsPageBase { SettingsPageSectionHeader { text: qsTr("Acessable things") - visible: userDetailsPage.restrictedThingAccess + visible: (userDetailsPage.userInfo.scopes & UserInfo.PermissionScopeAccessAllThings) !== UserInfo.PermissionScopeAccessAllThings Layout.fillWidth: true } @@ -434,15 +490,14 @@ SettingsPageBase { id: allowedThingsEntry Layout.fillWidth: true text: qsTr("Allowed things for this user") - visible: userDetailsPage.restrictedThingAccess + subText: userDetailsPage.userInfo.allowedThingIds.length + " " + qsTr("things accessable") + visible: (userDetailsPage.userInfo.scopes & UserInfo.PermissionScopeAccessAllThings) !== UserInfo.PermissionScopeAccessAllThings progressive: true onClicked: { - + pageStack.push(configureAllowedThingsComponent, {userInfo: userDetailsPage.userInfo}) } - } - SettingsPageSectionHeader { text: qsTr("Remove") } diff --git a/nymea-app/ui/thingconfiguration/ConfigureThingPage.qml b/nymea-app/ui/thingconfiguration/ConfigureThingPage.qml index 493fa8c0..768c0606 100644 --- a/nymea-app/ui/thingconfiguration/ConfigureThingPage.qml +++ b/nymea-app/ui/thingconfiguration/ConfigureThingPage.qml @@ -32,6 +32,7 @@ import "../delegates" SettingsPageBase { id: root + property Thing thing: null busy: d.pendingCommand != -1 @@ -47,12 +48,14 @@ SettingsPageBase { ThingInfoPane { id: infoPane + Layout.fillWidth: true thing: root.thing } Menu { id: deviceMenu + width: implicitWidth + app.margins x: parent.width - width @@ -194,6 +197,7 @@ SettingsPageBase { analogInputs: true analogOutputs: true } + Repeater { model: ioModel delegate: NymeaSwipeDelegate { @@ -269,6 +273,7 @@ SettingsPageBase { } property bool dirty: false } + Button { Layout.fillWidth: true Layout.leftMargin: app.margins @@ -295,13 +300,16 @@ SettingsPageBase { Component { id: errorDialog + ErrorDialog { } } Component { id: removeDialogComponent + NymeaDialog { id: removeDialog + title: qsTr("Remove thing?") text: qsTr("Are you sure you want to remove %1 and all associated settings?").arg(root.thing.name) standardButtons: Dialog.Yes | Dialog.No @@ -314,8 +322,10 @@ SettingsPageBase { Component { id: renameDialog + Dialog { id: dialog + width: parent.width * .8 x: (parent.width - width) / 2 y: app.margins @@ -340,6 +350,7 @@ SettingsPageBase { Component { id: ioConnectionsDialogComponent + NymeaDialog { id: ioConnectionDialog standardButtons: Dialog.NoButton @@ -356,18 +367,13 @@ SettingsPageBase { text: qsTr("Connect \"%1\" to:").arg(ioConnectionDialog.ioStateType.displayName) wrapMode: Text.WordWrap } -// Label { text: "\n" } // Fake in some spacing GridLayout { columns: (ioConnectionDialog.width / 400) * 2 -// Label { -// Layout.fillWidth: true -// text: qsTr("Thing") -// } - ComboBox { id: ioThingComboBox + model: ThingsProxy { id: connectableIODevices engine: _engine @@ -395,13 +401,9 @@ SettingsPageBase { } } -// Label { -// Layout.fillWidth: true -// text: (ioConnectionDialog.ioStateType.ioType == Types.IOTypeDigitalInput || ioConnectionDialog.ioStateType.ioType == Types.IOTypeAnalogInput) ? qsTr("Output") : qsTr("Input") -// } - ComboBox { id: ioStateComboBox + model: StateTypesProxy { id: connectableStateTypes stateTypes: connectableIODevices.get(ioThingComboBox.currentIndex).thingClass.stateTypes @@ -413,7 +415,7 @@ SettingsPageBase { textRole: "displayName" Layout.fillWidth: true onCountChanged: { -// print("loading for:", ioConnectionDialog.inputWatcher.ioConnection.outputStateTypeId) + // print("loading for:", ioConnectionDialog.inputWatcher.ioConnection.outputStateTypeId) for (var i = 0; i < connectableStateTypes.count; i++) { print("checking:", connectableStateTypes.get(i).id) if (ioConnectionDialog.ioStateType.ioType == Types.IOTypeDigitalInput || ioConnectionDialog.ioStateType.ioType == Types.IOTypeAnalogInput) { @@ -443,14 +445,16 @@ SettingsPageBase { checked: ioConnectionDialog.isInput ? ioConnectionDialog.inputWatcher.ioConnection.inverted : ioConnectionDialog.outputWatcher.ioConnection.inverted } } - } + } GridLayout { id: buttonGrid + columns: width > (cancelButton.implicitWidth + disconnectButton.implicitWidth + connectButton.implicitWidth) ? 4 : 1 layoutDirection: columns == 1 ? Qt.RightToLeft : Qt.LeftToRight + Item { Layout.fillWidth: true } @@ -461,6 +465,7 @@ SettingsPageBase { Layout.fillWidth: buttonGrid.columns === 1 onClicked: ioConnectionDialog.reject(); } + Button { id: disconnectButton text: qsTr("Disconnect") @@ -478,6 +483,7 @@ SettingsPageBase { ioConnectionDialog.reject(); } } + Button { id: connectButton text: qsTr("Connect") @@ -510,8 +516,6 @@ SettingsPageBase { } } } - - } } } From 3ba0c0405e3c9752c64e03ef57f5dd36376fa802 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 4 Nov 2025 16:26:42 +0100 Subject: [PATCH 43/50] Hide user settings if permission is missing --- libnymea-app/libnymea-app-core.h | 2 +- libnymea-app/types/userinfo.h | 12 +-- libnymea-app/usermanager.cpp | 18 +++- nymea-app/ui/system/UsersSettingsPage.qml | 108 ++++++++++++++-------- nymea-app/ui/utils/NymeaUtils.qml | 29 ++++++ 5 files changed, 123 insertions(+), 46 deletions(-) diff --git a/libnymea-app/libnymea-app-core.h b/libnymea-app/libnymea-app-core.h index cbc0ae1f..89498a89 100644 --- a/libnymea-app/libnymea-app-core.h +++ b/libnymea-app/libnymea-app-core.h @@ -372,7 +372,7 @@ void registerQmlTypes() { qmlRegisterType(uri, 1, 0, "ScriptAutoSaver"); qmlRegisterType(uri, 1, 0, "UserManager"); - qmlRegisterUncreatableType(uri, 1, 0, "UserInfo", "Get it from UserManager"); + qmlRegisterType(uri, 1, 0, "UserInfo"); qmlRegisterUncreatableType(uri, 1, 0, "TokenInfo", "Get it from TokenInfos"); qmlRegisterUncreatableType(uri, 1, 0, "TokenInfos", "Get it from UserManager"); qmlRegisterUncreatableType(uri, 1, 0, "Users", "Get it from UserManager"); diff --git a/libnymea-app/types/userinfo.h b/libnymea-app/types/userinfo.h index 5e180e51..d2db28fa 100644 --- a/libnymea-app/types/userinfo.h +++ b/libnymea-app/types/userinfo.h @@ -31,18 +31,18 @@ class UserInfo : public QObject { Q_OBJECT - Q_PROPERTY(QString username READ username NOTIFY usernameChanged) - Q_PROPERTY(QString email READ email NOTIFY emailChanged) - Q_PROPERTY(QString displayName READ displayName NOTIFY displayNameChanged) - Q_PROPERTY(PermissionScopes scopes READ scopes NOTIFY scopesChanged) - Q_PROPERTY(QList allowedThingIds READ allowedThingIds NOTIFY allowedThingIdsChanged) + Q_PROPERTY(QString username READ username WRITE setUsername NOTIFY usernameChanged) + Q_PROPERTY(QString email READ email WRITE setEmail NOTIFY emailChanged) + Q_PROPERTY(QString displayName READ displayName WRITE setDisplayName NOTIFY displayNameChanged) + Q_PROPERTY(PermissionScopes scopes READ scopes WRITE setScopes NOTIFY scopesChanged) + Q_PROPERTY(QList allowedThingIds READ allowedThingIds WRITE setAllowedThingIds NOTIFY allowedThingIdsChanged) public: enum PermissionScope { PermissionScopeNone = 0x0000, PermissionScopeControlThings = 0x0001, PermissionScopeConfigureThings = 0x0003, - PermissionScopeAccessAllThings = 0x0004, + PermissionScopeAccessAllThings = 0x0004, // Since 8.4 PermissionScopeExecuteRules = 0x0010, PermissionScopeConfigureRules = 0x0030, PermissionScopeAdmin = 0xFFFF, diff --git a/libnymea-app/usermanager.cpp b/libnymea-app/usermanager.cpp index 5cb403b5..c3d1b2a0 100644 --- a/libnymea-app/usermanager.cpp +++ b/libnymea-app/usermanager.cpp @@ -103,7 +103,14 @@ int UserManager::createUser(const QString &username, const QString &password, co if (m_engine->jsonRpcClient()->ensureServerVersion("6.0")) { params.insert("displayName", displayName); params.insert("email", email); - params.insert("scopes", UserInfo::scopesToList((UserInfo::PermissionScopes)permissionScopes)); + + // Backports compatibility for pre 8.4 + UserInfo::PermissionScopes scopes = static_cast(permissionScopes); + if (!m_engine->jsonRpcClient()->ensureServerVersion("8.4")) + scopes.setFlag(UserInfo::PermissionScopeAccessAllThings, false); + + + params.insert("scopes", UserInfo::scopesToList(scopes)); } if (m_engine->jsonRpcClient()->ensureServerVersion("8.4") && !allowedThingIds.isEmpty()) { @@ -145,7 +152,14 @@ int UserManager::setUserScopes(const QString &username, int scopes, const QList< { QVariantMap params; params.insert("username", username); - params.insert("scopes", UserInfo::scopesToList((UserInfo::PermissionScopes)scopes)); + + // Backports compatibility for pre 8.4 + UserInfo::PermissionScopes finalScopes = static_cast(scopes); + if (!m_engine->jsonRpcClient()->ensureServerVersion("8.4")) + finalScopes.setFlag(UserInfo::PermissionScopeAccessAllThings, false); + + params.insert("scopes", UserInfo::scopesToList(finalScopes)); + if (m_engine->jsonRpcClient()->ensureServerVersion("8.4") && !allowedThingIds.isEmpty()) { QVariantList thingIds; foreach (const QUuid &thingId, allowedThingIds) diff --git a/nymea-app/ui/system/UsersSettingsPage.qml b/nymea-app/ui/system/UsersSettingsPage.qml index 17ccdabe..50c1fde1 100644 --- a/nymea-app/ui/system/UsersSettingsPage.qml +++ b/nymea-app/ui/system/UsersSettingsPage.qml @@ -98,7 +98,7 @@ SettingsPageBase { Layout.fillWidth: true text: qsTr("Change password") iconName: "qrc:/icons/key.svg" - visible: !engine.jsonRpcClient.pushButtonAuthAvailable + visible: NymeaUtils.hasPermissionScope(engine.jsonRpcClient.permissions, UserInfo.PermissionScopeAdmin) && !engine.jsonRpcClient.pushButtonAuthAvailable onClicked: { var page = pageStack.push(changePasswordComponent) page.confirmed.connect(function(newPassword) { @@ -112,16 +112,15 @@ SettingsPageBase { text: qsTr("Edit user information") iconName: "qrc:/icons/edit.svg" onClicked: pageStack.push(editUserInfoComponent) - visible: !engine.jsonRpcClient.pushButtonAuthAvailable + visible: NymeaUtils.hasPermissionScope(engine.jsonRpcClient.permissions, UserInfo.PermissionScopeAdmin) && !engine.jsonRpcClient.pushButtonAuthAvailable } NymeaItemDelegate { Layout.fillWidth: true text: qsTr("Manage authorized devices") iconName: "qrc:/icons/smartphone.svg" - onClicked: { - pageStack.push(manageTokensComponent) - } + visible: NymeaUtils.hasPermissionScope(engine.jsonRpcClient.permissions, UserInfo.PermissionScopeAdmin) + onClicked: pageStack.push(manageTokensComponent) } SettingsPageSectionHeader { @@ -134,12 +133,9 @@ SettingsPageBase { text: qsTr("Manage users") visible: NymeaUtils.hasPermissionScope(engine.jsonRpcClient.permissions, UserInfo.PermissionScopeAdmin) && !engine.jsonRpcClient.pushButtonAuthAvailable iconName: "qrc:/icons/contact-group.svg" - onClicked: { - pageStack.push(manageUsersComponent) - } + onClicked: pageStack.push(manageUsersComponent) } - Component { id: editUserInfoComponent SettingsPageBase { @@ -199,14 +195,16 @@ SettingsPageBase { id: configureAllowedThingsPage property UserInfo userInfo: null + property bool existingUser: true + + title: qsTr("Accessable things for") + " \"" + userInfo.username + "\"" header: NymeaHeader { - text: root.title + text: configureAllowedThingsPage.title backButtonVisible: true onBackPressed: pageStack.pop() } - title: qsTr("Allowed things for") + " \"" + userInfo.username + "\"" ColumnLayout { anchors.fill: parent @@ -236,7 +234,10 @@ SettingsPageBase { checked: configureAllowedThingsPage.userInfo.thingAllowed(thingDelegate.thing.id) onCheckedChanged: { configureAllowedThingsPage.userInfo.allowThingId(thingDelegate.thing.id, checked) - userManager.setUserScopes(configureAllowedThingsPage.userInfo.username, configureAllowedThingsPage.userInfo.scopes, configureAllowedThingsPage.userInfo.allowedThingIds) + if (configureAllowedThingsPage.existingUser) { + // Only update if this user already exists + userManager.setUserScopes(configureAllowedThingsPage.userInfo.username, configureAllowedThingsPage.userInfo.scopes, configureAllowedThingsPage.userInfo.allowedThingIds) + } } } } @@ -438,7 +439,7 @@ SettingsPageBase { Repeater { id: permissionRepeater - model: NymeaUtils.scopesModel + model: engine.jsonRpcClient.ensureServerVersion("8.4") ? NymeaUtils.scopesModel : NymeaUtils.scopesModelPre8dot4 delegate: NymeaSwipeDelegate { Layout.fillWidth: true @@ -478,24 +479,22 @@ SettingsPageBase { } } - SettingsPageSectionHeader { text: qsTr("Acessable things") - visible: (userDetailsPage.userInfo.scopes & UserInfo.PermissionScopeAccessAllThings) !== UserInfo.PermissionScopeAccessAllThings + visible: engine.jsonRpcClient.ensureServerVersion("8.4") && + (userDetailsPage.userInfo.scopes & UserInfo.PermissionScopeAccessAllThings) !== UserInfo.PermissionScopeAccessAllThings Layout.fillWidth: true } - NymeaSwipeDelegate { id: allowedThingsEntry Layout.fillWidth: true text: qsTr("Allowed things for this user") subText: userDetailsPage.userInfo.allowedThingIds.length + " " + qsTr("things accessable") - visible: (userDetailsPage.userInfo.scopes & UserInfo.PermissionScopeAccessAllThings) !== UserInfo.PermissionScopeAccessAllThings + visible: engine.jsonRpcClient.ensureServerVersion("8.4") && + (userDetailsPage.userInfo.scopes & UserInfo.PermissionScopeAccessAllThings) !== UserInfo.PermissionScopeAccessAllThings progressive: true - onClicked: { - pageStack.push(configureAllowedThingsComponent, {userInfo: userDetailsPage.userInfo}) - } + onClicked: pageStack.push(configureAllowedThingsComponent, {userInfo: userDetailsPage.userInfo}) } SettingsPageSectionHeader { @@ -537,7 +536,13 @@ SettingsPageBase { id: createUserPage title: qsTr("Add a user") - property var permissionScopes: UserInfo.PermissionScopeNone + UserInfo { + id: newUserInfo + username: usernameTextField.text + email: emailTextField.text + displayName: displayNameTextField.text + + } SettingsPageSectionHeader { text: qsTr("User information") @@ -588,30 +593,59 @@ SettingsPageBase { text: qsTr("Permissions") } - Repeater { id: scopesRepeater - model: NymeaUtils.scopesModel - delegate: CheckDelegate { + model: engine.jsonRpcClient.ensureServerVersion("8.4") ? NymeaUtils.scopesModel : NymeaUtils.scopesModelPre8dot4 + + delegate: NymeaSwipeDelegate { + Layout.fillWidth: true - text: model.text - checked: (createUserPage.permissionScopes & model.scope) === model.scope - onClicked: { - var scopes = createUserPage.permissionScopes - if (checked) { - scopes |= model.scope - } else { - scopes &= ~model.scope - } - // make sure the new permissions are consistant before sending them to the core - scopes = NymeaUtils.getPermissionScopeAdjustments(model.scope, checked, scopes) - createUserPage.permissionScopes = scopes + text: model.text + subText: model.description + progressive: false + + CheckBox { + anchors.right: parent.right + anchors.rightMargin: app.margins + anchors.verticalCenter: parent.verticalCenter + enabled: model.scope === UserInfo.PermissionScopeAdmin || ((newUserInfo.scopes & UserInfo.PermissionScopeAdmin) !== UserInfo.PermissionScopeAdmin) + checked: (newUserInfo.scopes & model.scope) === model.scope + onClicked: { + var scopes = newUserInfo.scopes + if (checked) { + scopes |= model.scope + } else { + scopes &= ~model.scope + } + + // make sure the new permissions are consistant before sending them to the core + scopes = NymeaUtils.getPermissionScopeAdjustments(model.scope, checked, scopes) + newUserInfo.scopes = scopes + } } } } + SettingsPageSectionHeader { + text: qsTr("Acessable things") + visible: engine.jsonRpcClient.ensureServerVersion("8.4") && + (newUserInfo.scopes & UserInfo.PermissionScopeAccessAllThings) !== UserInfo.PermissionScopeAccessAllThings + Layout.fillWidth: true + } + + NymeaSwipeDelegate { + id: allowedThingsEntry + Layout.fillWidth: true + text: qsTr("Allowed things for this user") + subText: newUserInfo.allowedThingIds.length + " " + qsTr("things accessable") + visible: engine.jsonRpcClient.ensureServerVersion("8.4") && + (newUserInfo.scopes & UserInfo.PermissionScopeAccessAllThings) !== UserInfo.PermissionScopeAccessAllThings + progressive: true + onClicked: pageStack.push(configureAllowedThingsComponent, {userInfo: newUserInfo, existingUser: false}) + } + Button { text: qsTr("Create new user") Layout.fillWidth: true @@ -620,7 +654,7 @@ SettingsPageBase { enabled: usernameTextField.displayText.length >= 3 && passwordTextField.isValid onClicked: { createUserPage.busy = true - userManager.createUser(usernameTextField.displayText, passwordTextField.password, displayNameTextField.text, emailTextField.text, createUserPage.permissionScopes) + userManager.createUser(usernameTextField.displayText, passwordTextField.password, displayNameTextField.text, emailTextField.text, newUserInfo.scopes, newUserInfo.allowedThingIds) } } Connections { diff --git a/nymea-app/ui/utils/NymeaUtils.qml b/nymea-app/ui/utils/NymeaUtils.qml index b4c56ea1..0c274bc9 100644 --- a/nymea-app/ui/utils/NymeaUtils.qml +++ b/nymea-app/ui/utils/NymeaUtils.qml @@ -166,6 +166,35 @@ Item { return namedIcons[name] } + property ListModel scopesModelPre8dot4: ListModel { + ListElement { + text: qsTr("Admin") + description: qsTr("Full access to the system.") + scope: UserInfo.PermissionScopeAdmin + } + ListElement { + text: qsTr("Control things") + description: qsTr("Execute actions and use things and services.") + scope: UserInfo.PermissionScopeControlThings + } + ListElement { + text: qsTr("Configure things") + description: qsTr("Add new things and change settings.") + scope: UserInfo.PermissionScopeConfigureThings + } + ListElement { + text: qsTr("Execute magic") + description: qsTr("Execute rules, scenes and scripts.") + scope: UserInfo.PermissionScopeExecuteRules + } + ListElement { + text: qsTr("Configure magic") + description: qsTr("Create new rules and scripts in the system.") + scope: UserInfo.PermissionScopeConfigureRules + } + } + + property ListModel scopesModel: ListModel { ListElement { text: qsTr("Admin") From d486a5f61e2a752cd23a95f9b76e1bee8619f17c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 4 Nov 2025 16:26:42 +0100 Subject: [PATCH 44/50] Hide user settings if permission is missing --- libnymea-app/usermanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libnymea-app/usermanager.cpp b/libnymea-app/usermanager.cpp index c3d1b2a0..828cdfbe 100644 --- a/libnymea-app/usermanager.cpp +++ b/libnymea-app/usermanager.cpp @@ -160,7 +160,7 @@ int UserManager::setUserScopes(const QString &username, int scopes, const QList< params.insert("scopes", UserInfo::scopesToList(finalScopes)); - if (m_engine->jsonRpcClient()->ensureServerVersion("8.4") && !allowedThingIds.isEmpty()) { + if (m_engine->jsonRpcClient()->ensureServerVersion("8.4")) { QVariantList thingIds; foreach (const QUuid &thingId, allowedThingIds) thingIds.append(thingId); From 336e21aabce60f2d3e142df6d8233502fd727a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Thu, 6 Nov 2025 09:46:18 +0100 Subject: [PATCH 45/50] Add EV Dash experience --- experiences/evdash/evdash.pro | 29 +++ experiences/evdash/evdashmanager.cpp | 167 +++++++++++++++++ experiences/evdash/evdashmanager.h | 89 +++++++++ experiences/evdash/evdashusers.cpp | 108 +++++++++++ experiences/evdash/evdashusers.h | 55 ++++++ experiences/evdash/libnymea-app-evdash.h | 46 +++++ experiences/experiences.pro | 2 +- libnymea-app/jsonrpc/jsonrpcclient.cpp | 5 +- libnymea-app/usermanager.cpp | 2 +- nymea-app/main.cpp | 2 + nymea-app/nymea-app.pro | 30 +-- nymea-app/resources.qrc | 1 + nymea-app/ui/SettingsPage.qml | 11 ++ nymea-app/ui/system/EvDashSettingsPage.qml | 203 +++++++++++++++++++++ 14 files changed, 735 insertions(+), 15 deletions(-) create mode 100644 experiences/evdash/evdash.pro create mode 100644 experiences/evdash/evdashmanager.cpp create mode 100644 experiences/evdash/evdashmanager.h create mode 100644 experiences/evdash/evdashusers.cpp create mode 100644 experiences/evdash/evdashusers.h create mode 100644 experiences/evdash/libnymea-app-evdash.h create mode 100644 nymea-app/ui/system/EvDashSettingsPage.qml diff --git a/experiences/evdash/evdash.pro b/experiences/evdash/evdash.pro new file mode 100644 index 00000000..05d898d5 --- /dev/null +++ b/experiences/evdash/evdash.pro @@ -0,0 +1,29 @@ +TEMPLATE = lib +CONFIG += staticlib +TARGET = nymea-app-evdash + +QT -= gui +QT += network websockets quick + +include(../../shared.pri) + +LIBS += -L$${top_builddir}/libnymea-app/ -lnymea-app +INCLUDEPATH += $${top_srcdir}/libnymea-app/ + +android: { + LIBS += -L$${top_builddir}/libnymea-app/$${ANDROID_TARGET_ARCH} + PRE_TARGETDEPS += $$top_builddir/libnymea-app/$${ANDROID_TARGET_ARCH}/libnymea-app_$${ANDROID_TARGET_ARCH}.a +} + +HEADERS += \ + evdashmanager.h \ + evdashusers.h \ + libnymea-app-evdash.h + +SOURCES += \ + evdashmanager.cpp \ + evdashusers.cpp + +android: { + DESTDIR = $${ANDROID_TARGET_ARCH} +} diff --git a/experiences/evdash/evdashmanager.cpp b/experiences/evdash/evdashmanager.cpp new file mode 100644 index 00000000..cb960f2b --- /dev/null +++ b/experiences/evdash/evdashmanager.cpp @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright (C) 2013 - 2024, nymea GmbH +* Copyright (C) 2024 - 2025, chargebyte austria GmbH +* +* This file is part of nymea-app. +* +* nymea-app is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* nymea-app is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with nymea-app. If not, see . +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "evdashmanager.h" + +#include + +#include + +NYMEA_LOGGING_CATEGORY(dcEvDashExperience, "EvDashExperience") + +EvDashManager::EvDashManager(QObject *parent) + :QObject{parent}, + m_users{new EvDashUsers(this)} +{ + +} + +EvDashManager::~EvDashManager() +{ + if (m_engine) { + m_engine->jsonRpcClient()->unregisterNotificationHandler(this); + } +} + +EvDashUsers *EvDashManager::users() const +{ + return m_users; +} + +Engine *EvDashManager::engine() const +{ + return m_engine; +} + +void EvDashManager::setEngine(Engine *engine) +{ + if (m_engine == engine) + return; + + if (m_engine) + m_engine->jsonRpcClient()->unregisterNotificationHandler(this); + + m_engine = engine; + emit engineChanged(); + + if (m_engine) { + connect(engine, &Engine::destroyed, this, [engine, this]{ if (m_engine == engine) m_engine = nullptr; }); + + m_engine->jsonRpcClient()->registerNotificationHandler(this, "EvDash", "notificationReceived"); + m_engine->jsonRpcClient()->sendCommand("EvDash.GetEnabled", QVariantMap(), this, "getEnabledResponse"); + m_engine->jsonRpcClient()->sendCommand("EvDash.GetUsers", QVariantMap(), this, "getUsersResponse"); + } +} + +bool EvDashManager::enabled() const +{ + return m_enabled; +} + +int EvDashManager::setEnabled(bool enabled) +{ + QVariantMap params; + params.insert("enabled", enabled); + return m_engine->jsonRpcClient()->sendCommand("EvDash.SetEnabled", params, this, "setEnabledResponse"); +} + +int EvDashManager::addUser(const QString &username, const QString &password) +{ + QVariantMap params; + params.insert("username", username); + params.insert("password", password); + return m_engine->jsonRpcClient()->sendCommand("EvDash.AddUser", params, this, "addUserResponse"); +} + +int EvDashManager::removeUser(const QString &username) +{ + QVariantMap params; + params.insert("username", username); + return m_engine->jsonRpcClient()->sendCommand("EvDash.RemoveUser", params, this, "removeUserResponse"); +} + +void EvDashManager::notificationReceived(const QVariantMap &data) +{ + QString notification = data.value("notification").toString(); + QVariantMap params = data.value("params").toMap(); + + if (notification == "EvDash.EnabledChanged") { + bool enabled = params.value("enabled").toBool(); + if (m_enabled != enabled) { + m_enabled = enabled; + emit enabledChanged(); + } + } else if (notification == "EvDash.UserAdded") { + m_users->addUser(params.value("username").toString()); + } else if (notification == "EvDash.UserRemoved") { + m_users->removeUser(params.value("username").toString()); + } else { + qCDebug(dcEvDashExperience()) << "Unhandled notification received" << data; + } +} + +void EvDashManager::getEnabledResponse(int commandId, const QVariantMap ¶ms) +{ + Q_UNUSED(commandId) + qCDebug(dcEvDashExperience()) << "Response for GetEnabled request" << commandId << params; + + bool enabled = params.value("enabled").toBool(); + if (m_enabled != enabled) { + m_enabled = enabled; + emit enabledChanged(); + } +} + +void EvDashManager::setEnabledResponse(int commandId, const QVariantMap ¶ms) +{ + qCDebug(dcEvDashExperience()) << "Response for SetEnabled request" << commandId << params; + QMetaEnum metaEnum = QMetaEnum::fromType(); + EvDashError error = static_cast(metaEnum.keyToValue(params.value("evDashError").toByteArray().data())); + emit setEnabledReply(commandId, error); +} + +void EvDashManager::getUsersResponse(int commandId, const QVariantMap ¶ms) +{ + Q_UNUSED(commandId) + qCDebug(dcEvDashExperience()) << "Response for GetEnabled request" << commandId << params; + m_users->setUsers(params.value("usernames").toStringList()); +} + +void EvDashManager::addUserResponse(int commandId, const QVariantMap ¶ms) +{ + qCDebug(dcEvDashExperience()) << "Response for AddUser request" << commandId << params; + QMetaEnum metaEnum = QMetaEnum::fromType(); + EvDashError error = static_cast(metaEnum.keyToValue(params.value("evDashError").toByteArray().data())); + emit addUserReply(commandId, error); +} + +void EvDashManager::removeUserResponse(int commandId, const QVariantMap ¶ms) +{ + qCDebug(dcEvDashExperience()) << "Response for RemoveUser request" << commandId << params; + QMetaEnum metaEnum = QMetaEnum::fromType(); + EvDashError error = static_cast(metaEnum.keyToValue(params.value("evDashError").toByteArray().data())); + emit removeUserReply(commandId, error); +} + + diff --git a/experiences/evdash/evdashmanager.h b/experiences/evdash/evdashmanager.h new file mode 100644 index 00000000..01ba0332 --- /dev/null +++ b/experiences/evdash/evdashmanager.h @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright (C) 2013 - 2024, nymea GmbH +* Copyright (C) 2024 - 2025, chargebyte austria GmbH +* +* This file is part of nymea-app. +* +* nymea-app is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* nymea-app is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with nymea-app. If not, see . +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef EVDASHMANAGER_H +#define EVDASHMANAGER_H + +#include +#include + +#include "evdashusers.h" + +class EvDashManager : public QObject +{ + Q_OBJECT + Q_PROPERTY(Engine* engine READ engine WRITE setEngine NOTIFY engineChanged) + Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged FINAL) + Q_PROPERTY(EvDashUsers *users READ users CONSTANT FINAL) + +public: + enum EvDashError { + EvDashErrorNoError = 0, + EvDashErrorBackendError, + EvDashErrorDuplicateUser, + EvDashErrorUserNotFound, + EvDashErrorBadPassword + }; + Q_ENUM(EvDashError) + + explicit EvDashManager(QObject *parent = nullptr); + ~EvDashManager(); + + EvDashUsers *users() const; + + Engine* engine() const; + void setEngine(Engine *engine); + + bool enabled() const; + int setEnabled(bool enabled); + + Q_INVOKABLE int addUser(const QString &username, const QString &password); + Q_INVOKABLE int removeUser(const QString &username); + +signals: + void engineChanged(); + void enabledChanged(); + + void setEnabledReply(int commandId, EvDashManager::EvDashError error); + void addUserReply(int commandId, EvDashManager::EvDashError error); + void removeUserReply(int commandId, EvDashManager::EvDashError error); + +private slots: + void notificationReceived(const QVariantMap &data); + + void getEnabledResponse(int commandId, const QVariantMap ¶ms); + void setEnabledResponse(int commandId, const QVariantMap ¶ms); + + void getUsersResponse(int commandId, const QVariantMap ¶ms); + void addUserResponse(int commandId, const QVariantMap ¶ms); + void removeUserResponse(int commandId, const QVariantMap ¶ms); + +private: + Engine *m_engine = nullptr; + bool m_enabled = false; + EvDashUsers *m_users = nullptr; + +}; + +#endif // EVDASHMANAGER_H diff --git a/experiences/evdash/evdashusers.cpp b/experiences/evdash/evdashusers.cpp new file mode 100644 index 00000000..e3492804 --- /dev/null +++ b/experiences/evdash/evdashusers.cpp @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright (C) 2013 - 2024, nymea GmbH +* Copyright (C) 2024 - 2025, chargebyte austria GmbH +* +* This file is part of nymea-app. +* +* nymea-app is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* nymea-app is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with nymea-app. If not, see . +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "evdashusers.h" + +#include + +namespace { +inline bool localeLess(const QString &lhs, const QString &rhs) +{ + return QString::localeAwareCompare(lhs, rhs) < 0; +} +} + +EvDashUsers::EvDashUsers(QObject *parent) + : QAbstractListModel(parent) +{ + +} + +EvDashUsers::EvDashUsers(const QStringList &data, QObject *parent) + : QAbstractListModel(parent), m_data(data) +{ + +} + +int EvDashUsers::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return m_data.size(); +} + +QVariant EvDashUsers::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() >= m_data.size()) + return QVariant(); + + if (role == Qt::DisplayRole || role == NameRole) + return m_data.at(index.row()); + + return QVariant(); +} + +QHash EvDashUsers::roleNames() const +{ + QHash roles; + roles[NameRole] = "name"; + return roles; +} + +void EvDashUsers::setUsers(const QStringList &users) +{ + QStringList sortedUsers = users; + sortedUsers.removeDuplicates(); + std::sort(sortedUsers.begin(), sortedUsers.end(), localeLess); + + if (sortedUsers == m_data) + return; + + beginResetModel(); + m_data = sortedUsers; + endResetModel(); +} + +void EvDashUsers::addUser(const QString &user) +{ + if (user.isEmpty() || m_data.contains(user)) + return; + + const auto insertIt = std::lower_bound(m_data.begin(), m_data.end(), user, localeLess); + const int insertIndex = std::distance(m_data.begin(), insertIt); + + beginInsertRows(QModelIndex(), insertIndex, insertIndex); + m_data.insert(insertIndex, user); + endInsertRows(); +} + +void EvDashUsers::removeUser(const QString &user) +{ + int index = m_data.indexOf(user); + if (index < 0) + return; + + beginRemoveRows(QModelIndex(), index, index); + m_data.removeAt(index); + endRemoveRows(); +} diff --git a/experiences/evdash/evdashusers.h b/experiences/evdash/evdashusers.h new file mode 100644 index 00000000..991294fe --- /dev/null +++ b/experiences/evdash/evdashusers.h @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright (C) 2013 - 2024, nymea GmbH +* Copyright (C) 2024 - 2025, chargebyte austria GmbH +* +* This file is part of nymea-app. +* +* nymea-app is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* nymea-app is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with nymea-app. If not, see . +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef EVDASHUSERS_H +#define EVDASHUSERS_H + +#include +#include +#include + +class EvDashUsers : public QAbstractListModel +{ + Q_OBJECT +public: + enum Roles { DisplayRole = Qt::UserRole + 1, NameRole }; + + explicit EvDashUsers(QObject *parent = nullptr); + explicit EvDashUsers(const QStringList &data, QObject *parent = nullptr); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QHash roleNames() const override; + + void setUsers(const QStringList &users); + void addUser(const QString &username); + void removeUser(const QString &username); + +private: + QStringList m_data; + +}; + + +#endif // EVDASHUSERS_H diff --git a/experiences/evdash/libnymea-app-evdash.h b/experiences/evdash/libnymea-app-evdash.h new file mode 100644 index 00000000..040cf3e0 --- /dev/null +++ b/experiences/evdash/libnymea-app-evdash.h @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright (C) 2013 - 2024, nymea GmbH +* Copyright (C) 2024 - 2025, chargebyte austria GmbH +* +* This file is part of nymea-app. +* +* nymea-app is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* nymea-app is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with nymea-app. If not, see . +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef LIBNYMEA_APP_EVDASH_H +#define LIBNYMEA_APP_EVDASH_H + +#include "evdashmanager.h" +#include "evdashusers.h" + +#include + +namespace Nymea { + +namespace EvDash { + +void registerQmlTypes() { + qmlRegisterType("Nymea.EvDash", 1, 0, "EvDashManager"); + qmlRegisterUncreatableType("Nymea.EvDash", 1, 0, "EvDashUsers", "Get if from the EvDash Manager"); +} + +} + +} + +#endif // LIBNYMEA_APP_EVDASH_H diff --git a/experiences/experiences.pro b/experiences/experiences.pro index 298fcbc4..794d26d4 100644 --- a/experiences/experiences.pro +++ b/experiences/experiences.pro @@ -1,3 +1,3 @@ TEMPLATE = subdirs -SUBDIRS += airconditioning +SUBDIRS += airconditioning evdash diff --git a/libnymea-app/jsonrpc/jsonrpcclient.cpp b/libnymea-app/jsonrpc/jsonrpcclient.cpp index 76e15985..0687bd0c 100644 --- a/libnymea-app/jsonrpc/jsonrpcclient.cpp +++ b/libnymea-app/jsonrpc/jsonrpcclient.cpp @@ -668,7 +668,10 @@ void JsonRpcClient::helloReply(int /*commandId*/, const QVariantMap ¶ms) QString name = params.value("name").toString(); m_experiences.clear(); foreach (const QVariant &experience, params.value("experiences").toList()) { - m_experiences.insert(experience.toMap().value("name").toString(), experience.toMap().value("version").toString()); + QString experienceName = experience.toMap().value("name").toString(); + QString experienceVersion = experience.toMap().value("version").toString(); + m_experiences.insert(experienceName, experienceVersion); + qCInfo(dcJsonRpc()) << "Experience available:" << experienceName << experienceVersion; } QString protoVersionString = params.value("protocol version").toString(); diff --git a/libnymea-app/usermanager.cpp b/libnymea-app/usermanager.cpp index 828cdfbe..c9cab670 100644 --- a/libnymea-app/usermanager.cpp +++ b/libnymea-app/usermanager.cpp @@ -163,7 +163,7 @@ int UserManager::setUserScopes(const QString &username, int scopes, const QList< if (m_engine->jsonRpcClient()->ensureServerVersion("8.4")) { QVariantList thingIds; foreach (const QUuid &thingId, allowedThingIds) - thingIds.append(thingId); + thingIds.append(thingId.toString()); params.insert("allowedThingIds", thingIds); } diff --git a/nymea-app/main.cpp b/nymea-app/main.cpp index 1acb1832..740bf417 100644 --- a/nymea-app/main.cpp +++ b/nymea-app/main.cpp @@ -48,6 +48,7 @@ #include "libnymea-app-core.h" #include "libnymea-app-airconditioning.h" +#include "libnymea-app-evdash.h" #include "stylecontroller.h" #include "pushnotifications.h" @@ -145,6 +146,7 @@ int main(int argc, char *argv[]) Nymea::Core::registerQmlTypes(); Nymea::AirConditioning::registerQmlTypes(); + Nymea::EvDash::registerQmlTypes(); QQmlApplicationEngine *engine = new QQmlApplicationEngine(); diff --git a/nymea-app/nymea-app.pro b/nymea-app/nymea-app.pro index a16746fa..fa60ddf3 100644 --- a/nymea-app/nymea-app.pro +++ b/nymea-app/nymea-app.pro @@ -13,25 +13,29 @@ qtHaveModule(webview) { } INCLUDEPATH += $$top_srcdir/libnymea-app \ - $$top_srcdir/experiences/airconditioning + $$top_srcdir/experiences/airconditioning \ + $$top_srcdir/experiences/evdash + +linux:!android:LIBS += -L$$top_builddir/libnymea-app/ -lnymea-app \ + -L$$top_builddir/experiences/airconditioning -lnymea-app-airconditioning \ + -L$$top_builddir/experiences/evdash -lnymea-app-evdash -linux:!android: LIBS += -L$$top_builddir/libnymea-app/ -lnymea-app -L$$top_builddir/experiences/airconditioning -lnymea-app-airconditioning win32:Debug:LIBS += -L$$top_builddir/libnymea-app/debug -lnymea-app \ - -L$$top_builddir/experiences/airconditioning/debug -lnymea-app-airconditioning -win32:Release:LIBS += -L$$top_builddir/libnymea-app/release -lnymea-app \ - -L$$top_builddir/experiences/airconditioning/release -lnymea-app-airconditioning + -L$$top_builddir/experiences/airconditioning/debug -lnymea-app-airconditioning \ + -L$$top_builddir/experiences/evdash/debug -lnymea-app-evdash + +win32:Release:LIBS += -L$$top_builddir/libnymea-app/release -lnymea-app \ + -L$$top_builddir/experiences/airconditioning/release -lnymea-app-airconditioning \ + -L$$top_builddir/experiences/evdash/release -lnymea-app-evdash -win32:Debug:PRE_TARGETDEPS += $$top_builddir/libnymea-app/debug/nymea-app.lib \ - $$top_builddir/experiences/airconditioning/debug/nymea-app-airconditioning.lib -win32:Release:PRE_TARGETDEPS += $$top_builddir/libnymea-app/release/nymea-app.lib \ - $$top_builddir/experiences/airconditioning/release/nymea-app-airconditioning.lib win32:CXX_FLAGS += /w linux:!android:!nozeroconf:LIBS += -lavahi-client -lavahi-common linux:!android:PRE_TARGETDEPS += $$top_builddir/libnymea-app/libnymea-app.a \ - $$top_builddir/experiences/airconditioning/libnymea-app-airconditioning.a + $$top_builddir/experiences/airconditioning/libnymea-app-airconditioning.a \ + $$top_builddir/experiences/evdash/libnymea-app-evdash.a HEADERS += \ configuredhostsmodel.h \ @@ -94,7 +98,7 @@ android { include(../3rdParty/android/android_openssl/openssl.pri) ANDROID_MIN_SDK_VERSION = 21 - ANDROID_TARGET_SDK_VERSION = 35 + ANDROID_TARGET_SDK_VERSION = 36 HEADERS += platformintegration/android/platformhelperandroid.h \ platformintegration/android/platformpermissionsandroid.h \ @@ -104,9 +108,11 @@ android { CORE_LIBS += -L$${top_builddir}/libnymea-app/$${ANDROID_TARGET_ARCH} AIRCONDITIONING_LIBS += -L$${top_builddir}/experiences/airconditioning/$${ANDROID_TARGET_ARCH} + EVDASH_LIBS += -L$${top_builddir}/experiences/evdash/$${ANDROID_TARGET_ARCH} LIBS += $${CORE_LIBS} -lnymea-app_$${ANDROID_TARGET_ARCH} \ - $${AIRCONDITIONING_LIBS} -lnymea-app-airconditioning_$${ANDROID_TARGET_ARCH} + $${AIRCONDITIONING_LIBS} -lnymea-app-airconditioning_$${ANDROID_TARGET_ARCH} \ + $${EVDASH_LIBS} -lnymea-app-evdash_$${ANDROID_TARGET_ARCH} versioninfo.files = ../version.txt versioninfo.path = / diff --git a/nymea-app/resources.qrc b/nymea-app/resources.qrc index 4a7c56a7..7900a598 100644 --- a/nymea-app/resources.qrc +++ b/nymea-app/resources.qrc @@ -325,5 +325,6 @@ ui/shaders/coloricon.frag.qsb ui/shaders/brightnesscircle.frag.qsb ui/shaders/colorizedimage.frag.qsb + ui/system/EvDashSettingsPage.qml diff --git a/nymea-app/ui/SettingsPage.qml b/nymea-app/ui/SettingsPage.qml index 5f113aa8..c5489b13 100644 --- a/nymea-app/ui/SettingsPage.qml +++ b/nymea-app/ui/SettingsPage.qml @@ -143,6 +143,17 @@ Page { onClicked:pageStack.push(Qt.resolvedUrl("system/PluginsPage.qml")) } + + SettingsTile { + Layout.fillWidth: true + iconSource: "qrc:/icons/dashboard.svg" + text: qsTr("EV Dash") + subText: qsTr("Dashboard settings") + visible: NymeaUtils.hasPermissionScope(engine.jsonRpcClient.permissions, UserInfo.PermissionScopeAdmin) && + (engine.jsonRpcClient.experiences.hasOwnProperty("EvDash")) + onClicked:pageStack.push(Qt.resolvedUrl("system/EvDashSettingsPage.qml")) + } + SettingsTile { Layout.fillWidth: true iconSource: "qrc:/icons/sdk.svg" diff --git a/nymea-app/ui/system/EvDashSettingsPage.qml b/nymea-app/ui/system/EvDashSettingsPage.qml new file mode 100644 index 00000000..af8b67a2 --- /dev/null +++ b/nymea-app/ui/system/EvDashSettingsPage.qml @@ -0,0 +1,203 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2025, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea. +* This project including source code and documentation is protected by +* copyright law, and remains the property of nymea GmbH. All rights, including +* reproduction, publication, editing and translation, are reserved. The use of +* this project is subject to the terms of a license agreement to be concluded +* with nymea GmbH in accordance with the terms of use of nymea GmbH, available +* under https://nymea.io/license +* +* GNU General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the +* terms of the GNU General Public License as published by the Free Software +* Foundation, GNU version 3. This project is distributed in the hope that it +* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +* Public License for more details. +* +* You should have received a copy of the GNU General Public License along with +* this project. If not, see . +* +* For any further details and any questions please contact us under +* contact@nymea.io or see our FAQ/Licensing Information on +* https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +import QtQuick 2.9 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 + +import Nymea 1.0 +import Nymea.EvDash 1.0 + +import "../components" + +SettingsPageBase { + id: root + + header: NymeaHeader { + text: qsTr("EV Dash") + onBackPressed: pageStack.pop() + + HeaderButton { + imageSource: Qt.resolvedUrl("qrc:/icons/add.svg") + onClicked: { + var popup = addUserPopup.createObject(app); + popup.open(); + } + } + } + + EvDashManager { + id: evDashManager + engine: _engine + } + + Component { + id: errorDialog + ErrorDialog {} + } + + + Component { + id: removeUserPopup + NymeaDialog { + id: removeUserDialog + + property string username + + headerIcon: "qrc:/icons/dialog-warning-symbolic.svg" + title: qsTr("Remove user") + text: qsTr("Are you sure you want to remove \"%1\"?").arg(username) + + onAccepted: { + evDashManager.removeUser(username); + popup.close(); + } + } + } + + Connections { + target: evDashManager + onAddUserReply: { + if (error === EvDashManager.EvDashErrorNoError) + return + + var text; + switch (error) { + case EvDashManager.EvDashErrorDuplicateUser: + text = qsTr("The given username is already in use. Please choose a different username."); + break; + case EvDashManager.EvDashErrorBadPassword: + text = qsTr("The given password is not valid."); + break; + default: + text = qsTr("Un unexpected error happened when creating the user. We're sorry for this. (Error code: %1)").arg(error); + break; + } + + var popup = errorDialog.createObject(app, {text: text}); + popup.open() + } + + onRemoveUserReply: { + if (error === EvDashManager.EvDashErrorNoError) + return + + var text; + switch (error) { + case EvDashManager.EvDashErrorDuplicateUser: + text = qsTr("The given username is already in use. Please choose a different username."); + break; + case EvDashManager.EvDashErrorBadPassword: + text = qsTr("The given password is not valid."); + break; + default: + text = qsTr("Un unexpected error happened when creating the user. We're sorry for this. (Error code: %1)").arg(error); + break; + } + + var popup = errorDialog.createObject(app, {text: text}); + popup.open() + } + } + + Component { + id: addUserPopup + + NymeaDialog { + id: addUserDialog + + title: qsTr("Create new user") + standardButtons: Dialog.NoButton + + Label { text: qsTr("Username") } + + NymeaTextField { + id: usernameTextField + Layout.fillWidth: true + } + + Label { text: qsTr("Password") } + + PasswordTextField { + id: passwordTextField + + Layout.fillWidth: true + minPasswordLength: 4 + requireSpecialChar: false + requireNumber: false + requireUpperCaseLetter: false + requireLowerCaseLetter: false + } + + Button { + Layout.fillWidth: true + text: qsTr("Add user") + onClicked: { + evDashManager.addUser(usernameTextField.text, passwordTextField.password) + addUserDialog.close() + } + } + + Button { + Layout.fillWidth: true + text: qsTr("Cancel") + onClicked: { + addUserDialog.close() + } + } + } + } + + + SwitchDelegate { + text: qsTr("Dashboard enabled") + checked: evDashManager.enabled + onCheckedChanged: evDashManager.enabled = checked + Layout.fillWidth: true + } + + SettingsPageSectionHeader { + text: qsTr("Manage users") + } + + Repeater { + id: usersList + model: evDashManager.users + + delegate: NymeaItemDelegate { + Layout.fillWidth: true + text: model.name + onClicked: { + var popup = removeUserPopup.createObject(app, {username: model.name}); + popup.open() + } + } + } +} From 871e2c0ce8f144d997a5e75f4dc56b4ea131b6df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 9 Dec 2025 15:06:49 +0100 Subject: [PATCH 46/50] Fix bluetooth wifi setup for bluez backends --- libnymea-app/wifisetup/bluetoothdiscovery.cpp | 5 ++++- libnymea-app/wifisetup/btwifisetup.cpp | 13 +++++++++-- .../android/platformpermissionsandroid.cpp | 10 +++++++-- nymea-app/ui/connection/ConnectionWizard.qml | 22 ++++++++++--------- 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/libnymea-app/wifisetup/bluetoothdiscovery.cpp b/libnymea-app/wifisetup/bluetoothdiscovery.cpp index eb185ebe..f1c20f55 100644 --- a/libnymea-app/wifisetup/bluetoothdiscovery.cpp +++ b/libnymea-app/wifisetup/bluetoothdiscovery.cpp @@ -166,10 +166,13 @@ void BluetoothDiscovery::onBluetoothHostModeChanged(const QBluetoothLocalDevice: connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &BluetoothDiscovery::deviceDiscovered); #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceUpdated, this, &BluetoothDiscovery::deviceDiscovered); +#elif (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) + connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::errorOccurred, this, &BluetoothDiscovery::onError); +#else + connect(m_discoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)), this, SLOT(onError(QBluetoothDeviceDiscoveryAgent::Error))); #endif connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &BluetoothDiscovery::discoveryFinished); connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::canceled, this, &BluetoothDiscovery::discoveryCancelled); - connect(m_discoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)), this, SLOT(onError(QBluetoothDeviceDiscoveryAgent::Error))); } if (m_discoveryEnabled && !m_discoveryAgent->isActive()) { start(); diff --git a/libnymea-app/wifisetup/btwifisetup.cpp b/libnymea-app/wifisetup/btwifisetup.cpp index ad153b65..e1f3d101 100644 --- a/libnymea-app/wifisetup/btwifisetup.cpp +++ b/libnymea-app/wifisetup/btwifisetup.cpp @@ -54,6 +54,10 @@ BtWiFiSetup::BtWiFiSetup(QObject *parent) : QObject(parent) { m_accessPoints = new WirelessAccessPoints(this); qRegisterMetaType("const BluetoothDeviceInfo*"); + + connect(this, &BtWiFiSetup::bluetoothStatusChanged, this, [this](){ + qCDebug(dcBtWiFiSetup()) << "Bluetooth status changed" << m_bluetoothStatus; + }); } BtWiFiSetup::~BtWiFiSetup() @@ -81,13 +85,18 @@ void BtWiFiSetup::connectToDevice(const BluetoothDeviceInfo *device) } m_btController = QLowEnergyController::createCentral(device->bluetoothDeviceInfo(), this); - connect(m_btController, &QLowEnergyController::connected, this, [this](){ - qCInfo(dcBtWiFiSetup()) << "Bluetooth connected"; + connect(m_btController, &QLowEnergyController::connected, this, [this, device](){ + qCInfo(dcBtWiFiSetup()) << "Bluetooth connected" << device->address() << device->name(); m_btController->discoverServices(); m_bluetoothStatus = BluetoothStatusConnectedToBluetooth; emit bluetoothStatusChanged(m_bluetoothStatus); }, Qt::QueuedConnection); + + connect(m_btController, &QLowEnergyController::stateChanged, this, [](QLowEnergyController::ControllerState state){ + qCInfo(dcBtWiFiSetup()) << "Bluetooth constroller state changed" << state; + }); + connect(m_btController, &QLowEnergyController::disconnected, this, [this](){ qCInfo(dcBtWiFiSetup()) << "Bluetooth disconnected"; m_bluetoothStatus = BluetoothStatusDisconnected; diff --git a/nymea-app/platformintegration/android/platformpermissionsandroid.cpp b/nymea-app/platformintegration/android/platformpermissionsandroid.cpp index d8f1e5dd..45fd8871 100644 --- a/nymea-app/platformintegration/android/platformpermissionsandroid.cpp +++ b/nymea-app/platformintegration/android/platformpermissionsandroid.cpp @@ -65,6 +65,8 @@ PlatformPermissions::PermissionStatus PlatformPermissionsAndroid::checkPermissio switch (platformPermission) { case PlatformPermissions::PermissionBluetooth: { QBluetoothPermission permission; + // Only request scan/connect access; advertising isn't needed and isn't declared in the manifest. + permission.setCommunicationModes(QBluetoothPermission::Access); const auto permissionStatus = qApp->checkPermission(permission); @@ -194,7 +196,10 @@ void PlatformPermissionsAndroid::requestPermission(PlatformPermissions::Permissi switch (platformPermission) { case PlatformPermissions::PermissionBluetooth: qCDebug(dcPlatformPermissions()) << "Requesting bluetooth permission"; - qApp->requestPermission(QBluetoothPermission{}, [platformPermission](const QPermission &permission) { + { + QBluetoothPermission permission; + permission.setCommunicationModes(QBluetoothPermission::Access); + qApp->requestPermission(permission, [platformPermission](const QPermission &permission) { if (permission.status() == Qt::PermissionStatus::Denied) { qCWarning(dcPlatformPermissions()) << "Bluetooth permission denied."; s_instance->m_requestedButDeniedPermissions.append(platformPermission); @@ -204,7 +209,8 @@ void PlatformPermissionsAndroid::requestPermission(PlatformPermissions::Permissi qCDebug(dcPlatformPermissions()) << "Bluetooth permission granted."; emit s_instance->bluetoothPermissionChanged(); - }); + }); + } break; case PlatformPermissions::PermissionLocation: { QLocationPermission locationPermission; diff --git a/nymea-app/ui/connection/ConnectionWizard.qml b/nymea-app/ui/connection/ConnectionWizard.qml index c309fcc4..c8e48337 100644 --- a/nymea-app/ui/connection/ConnectionWizard.qml +++ b/nymea-app/ui/connection/ConnectionWizard.qml @@ -297,7 +297,7 @@ WizardPageBase { callback: function() { var nymeaHost = hostsProxy.get(index); var connectionInfoDialog = Qt.createComponent("/ui/components/ConnectionInfoDialog.qml") - print("**", connectionInfoDialog.errorString()) + console.log("**", connectionInfoDialog.errorString()) var popup = connectionInfoDialog.createObject(app,{nymeaEngine: engine, nymeaHost: nymeaHost}) popup.open() popup.connectionSelected.connect(function(connection) { @@ -322,7 +322,7 @@ WizardPageBase { onNext: { var rpcUrl = manualEntry.rpcUrl; - print("Try to connect ", rpcUrl) + console.log("Try to connect ", rpcUrl) var host = nymeaDiscovery.nymeaHosts.createWanHost("Manual connection", rpcUrl); engine.jsonRpcClient.connectToHost(host) } @@ -390,8 +390,8 @@ WizardPageBase { BtWiFiSetup { id: wifiSetup - onBluetoothStatusChanged: { - print("status changed", status) + onBluetoothStatusChanged: (status) => { + console.log("status changed", status) switch (status) { case BtWiFiSetup.BluetoothStatusDisconnected: pageStack.pop(wirelessBluetoothDiscoveryPage) @@ -419,12 +419,12 @@ WizardPageBase { onCurrentConnectionChanged: { if (wifiSetup.currentConnection) { - print("**** connected!") + console.log("**** connected!") pageStack.push(wirelessConnectionCompletedComponent, {wifiSetup: wifiSetup}) } } onWirelessStatusChanged: { - print("Wireless status changed:", wifiSetup.networkStatus) + console.log("Wireless status changed:", wifiSetup.networkStatus) if (wifiSetup.wirelessStatus === BtWiFiSetup.WirelessStatusFailed) { pageStack.pop() } @@ -452,7 +452,9 @@ WizardPageBase { BusyIndicator { anchors.centerIn: parent - visible: bluetoothDiscovery.discovering && deviceInfosProxy.count == 0 && bluetoothDiscovery.bluetoothAvailable && bluetoothDiscovery.bluetoothEnabled && PlatformHelper.locationServicesEnabled + visible: bluetoothDiscovery.discovering && deviceInfosProxy.count === 0 && + bluetoothDiscovery.bluetoothAvailable && bluetoothDiscovery.bluetoothEnabled && + PlatformHelper.locationServicesEnabled } delegate: NymeaSwipeDelegate { @@ -609,7 +611,7 @@ WizardPageBase { } onClicked: { - print("Connect to ", model.ssid, " --> ", model.macAddress) + console.log("Connect to ", model.ssid, " --> ", model.macAddress) if (model.selectedNetwork) { pageStack.push(networkInformationPage, { ssid: model.ssid}) } else { @@ -642,7 +644,7 @@ WizardPageBase { onBack: pageStack.pop(); onNext: { - print("connecting to", ssidTextField.text, passwordTextField.password) + console.log("connecting to", ssidTextField.text, passwordTextField.password) wifiSetup.connectDeviceToWiFi(ssidTextField.text, passwordTextField.password, true) pageStack.push(wirelessConnectingWiFiComponent) } @@ -690,7 +692,7 @@ WizardPageBase { showNextButton: passwordTextField.isValidPassword onNext: { - print("connecting to", ssid, passwordTextField.password) + console.log("connecting to", ssid, passwordTextField.password) wifiSetup.connectDeviceToWiFi(ssid, passwordTextField.password) pageStack.push(wirelessConnectingWiFiComponent) } From 0f8c2a879e8f53d4ef07bc3f2792242eac5670c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 9 Dec 2025 15:47:17 +0100 Subject: [PATCH 47/50] android: Update permissions for searching bluetooth devices --- .../android/platformpermissionsandroid.cpp | 55 ++++++++++++++++--- packaging/android/AndroidManifest.xml | 3 +- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/nymea-app/platformintegration/android/platformpermissionsandroid.cpp b/nymea-app/platformintegration/android/platformpermissionsandroid.cpp index 45fd8871..3146de52 100644 --- a/nymea-app/platformintegration/android/platformpermissionsandroid.cpp +++ b/nymea-app/platformintegration/android/platformpermissionsandroid.cpp @@ -90,6 +90,25 @@ PlatformPermissions::PermissionStatus PlatformPermissionsAndroid::checkPermissio status = PermissionStatusNotDetermined; break; } + + // Some Android/Qt stacks still gate BLE scans on location permission; ensure it is present alongside bluetooth. + if (status != PermissionStatusDenied) { + QLocationPermission locationPermission; + locationPermission.setAccuracy(QLocationPermission::Precise); + const auto locationStatus = qApp->checkPermission(locationPermission); + switch (locationStatus) { + case Qt::PermissionStatus::Granted: + break; + case Qt::PermissionStatus::Denied: + qCWarning(dcPlatformPermissions()) << "Location permission denied but required for bluetooth scanning."; + status = PermissionStatusDenied; + break; + case Qt::PermissionStatus::Undetermined: + qCDebug(dcPlatformPermissions()) << "Location permission not yet requested but required for bluetooth scanning."; + status = PermissionStatusNotDetermined; + break; + } + } break; } case PlatformPermissions::PermissionLocalNetwork: { @@ -194,24 +213,44 @@ PlatformPermissions::PermissionStatus PlatformPermissionsAndroid::checkPermissio void PlatformPermissionsAndroid::requestPermission(PlatformPermissions::Permission platformPermission) { switch (platformPermission) { - case PlatformPermissions::PermissionBluetooth: + case PlatformPermissions::PermissionBluetooth: { qCDebug(dcPlatformPermissions()) << "Requesting bluetooth permission"; { QBluetoothPermission permission; permission.setCommunicationModes(QBluetoothPermission::Access); qApp->requestPermission(permission, [platformPermission](const QPermission &permission) { - if (permission.status() == Qt::PermissionStatus::Denied) { - qCWarning(dcPlatformPermissions()) << "Bluetooth permission denied."; - s_instance->m_requestedButDeniedPermissions.append(platformPermission); - } + if (permission.status() == Qt::PermissionStatus::Denied) { + qCWarning(dcPlatformPermissions()) << "Bluetooth permission denied."; + s_instance->m_requestedButDeniedPermissions.append(platformPermission); + } - if (permission.status() == Qt::PermissionStatus::Granted) - qCDebug(dcPlatformPermissions()) << "Bluetooth permission granted."; + if (permission.status() == Qt::PermissionStatus::Granted) + qCDebug(dcPlatformPermissions()) << "Bluetooth permission granted."; - emit s_instance->bluetoothPermissionChanged(); + emit s_instance->bluetoothPermissionChanged(); + }); + } + + QLocationPermission locationPermission; + locationPermission.setAccuracy(QLocationPermission::Precise); + const auto locationStatus = qApp->checkPermission(locationPermission); + if (locationStatus != Qt::PermissionStatus::Granted) { + qCDebug(dcPlatformPermissions()) << "Requesting location permission needed for bluetooth scanning on this Android version."; + qApp->requestPermission(locationPermission, [platformPermission](const QPermission &permission) { + if (permission.status() == Qt::PermissionStatus::Denied) { + qCWarning(dcPlatformPermissions()) << "Location permission denied."; + s_instance->m_requestedButDeniedPermissions.append(platformPermission); + } + + if (permission.status() == Qt::PermissionStatus::Granted) + qCDebug(dcPlatformPermissions()) << "Location permission granted."; + + emit s_instance->locationPermissionChanged(); + emit s_instance->bluetoothPermissionChanged(); }); } break; + } case PlatformPermissions::PermissionLocation: { QLocationPermission locationPermission; locationPermission.setAccuracy(QLocationPermission::Precise); diff --git a/packaging/android/AndroidManifest.xml b/packaging/android/AndroidManifest.xml index 79c49837..c8f3b70e 100644 --- a/packaging/android/AndroidManifest.xml +++ b/packaging/android/AndroidManifest.xml @@ -8,7 +8,8 @@ - + From 238e86c930d40f01bfc051e93bd8ba642a10e680 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 9 Dec 2025 16:32:59 +0100 Subject: [PATCH 48/50] iOS: Update bluetooth permission handling to the new QPermission system --- libnymea-app/jsonrpc/jsonrpcclient.cpp | 10 -- libnymea-app/wifisetup/bluetoothdiscovery.cpp | 31 +++-- nymea-app/nymea-app.pro | 18 +-- .../ios/platformpermissionsios.cpp | 11 +- .../ios/platformpermissionsios.h | 9 +- .../ios/platformpermissionsios.mm | 116 ++++++++++++++++-- packaging/ios/Info.plist.cmake.in | 8 ++ version.txt | 2 +- 8 files changed, 160 insertions(+), 45 deletions(-) diff --git a/libnymea-app/jsonrpc/jsonrpcclient.cpp b/libnymea-app/jsonrpc/jsonrpcclient.cpp index 0687bd0c..4f637bfd 100644 --- a/libnymea-app/jsonrpc/jsonrpcclient.cpp +++ b/libnymea-app/jsonrpc/jsonrpcclient.cpp @@ -77,16 +77,6 @@ void JsonRpcClient::registerNotificationHandler(QObject *handler, const QString m_notificationHandlers.insert(nameSpace, handler); m_notificationHandlerMethods.insert(handler, method); - // Clean up if the handler gets destroyed so we don't dereference dangling pointers when - // processing notifications. - connect(handler, &QObject::destroyed, this, [this](QObject *obj){ - for (const QString &ns : m_notificationHandlers.keys(obj)) { - m_notificationHandlers.remove(ns, obj); - } - m_notificationHandlerMethods.remove(obj); - setNotificationsEnabled(); - }); - setNotificationsEnabled(); } diff --git a/libnymea-app/wifisetup/bluetoothdiscovery.cpp b/libnymea-app/wifisetup/bluetoothdiscovery.cpp index f1c20f55..a384c73f 100644 --- a/libnymea-app/wifisetup/bluetoothdiscovery.cpp +++ b/libnymea-app/wifisetup/bluetoothdiscovery.cpp @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include Q_DECLARE_LOGGING_CATEGORY(dcBluetoothDiscovery); @@ -64,8 +66,6 @@ BluetoothDiscovery::BluetoothDiscovery(QObject *parent) : #else // Note: on iOS there is no QBluetoothLocalDevice available, therefore we have to assume there is one and // start the discovery agent with the default constructor. - // https://bugreports.qt.io/browse/QTBUG-65547 - m_bluetoothAvailable = true; // Always start with assuming BT is enabled @@ -88,13 +88,16 @@ bool BluetoothDiscovery::bluetoothEnabled() const #ifdef Q_OS_IOS return m_bluetoothAvailable && m_bluetoothEnabled; #endif + qCDebug(dcBluetoothDiscovery) << "bluetoothEnabled(): m_bluetoothAvailable:" << m_bluetoothAvailable; return m_bluetoothAvailable && m_localDevice->hostMode() != QBluetoothLocalDevice::HostPoweredOff; } -void BluetoothDiscovery::setBluetoothEnabled(bool bluetoothEnabled) { - if (!m_bluetoothAvailable) { + +void BluetoothDiscovery::setBluetoothEnabled(bool bluetoothEnabled) +{ + if (!m_bluetoothAvailable) return; - } + if (bluetoothEnabled) { if (m_localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff) { m_localDevice->powerOn(); @@ -151,26 +154,30 @@ void BluetoothDiscovery::onBluetoothHostModeChanged(const QBluetoothLocalDevice: #endif emit bluetoothEnabledChanged(false); break; + default: // Note: discovery works in all other modes #ifdef Q_OS_IOS m_bluetoothEnabled = true; #endif emit bluetoothEnabledChanged(hostMode != QBluetoothLocalDevice::HostPoweredOff); + if (!m_discoveryAgent) { #ifdef Q_OS_ANDROID m_discoveryAgent = new QBluetoothDeviceDiscoveryAgent(m_localDevice->address(), this); #else m_discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this); #endif - connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &BluetoothDiscovery::deviceDiscovered); #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceUpdated, this, &BluetoothDiscovery::deviceDiscovered); -#elif (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) +#endif + +#if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::errorOccurred, this, &BluetoothDiscovery::onError); #else connect(m_discoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)), this, SLOT(onError(QBluetoothDeviceDiscoveryAgent::Error))); #endif + connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &BluetoothDiscovery::deviceDiscovered); connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &BluetoothDiscovery::discoveryFinished); connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::canceled, this, &BluetoothDiscovery::discoveryCancelled); } @@ -241,13 +248,11 @@ void BluetoothDiscovery::onError(const QBluetoothDeviceDiscoveryAgent::Error &er void BluetoothDiscovery::start() { - if (!m_discoveryAgent || !bluetoothEnabled()) { + if (!m_discoveryAgent || !bluetoothEnabled()) return; - } - if (m_discoveryAgent->isActive()) { + if (m_discoveryAgent->isActive()) m_discoveryAgent->stop(); - } foreach (const QBluetoothDeviceInfo &info, m_discoveryAgent->discoveredDevices()) { qCDebug(dcBluetoothDiscovery()) << "Already discovered device:" << info.name(); @@ -255,7 +260,9 @@ void BluetoothDiscovery::start() } qCDebug(dcBluetoothDiscovery) << "Starting discovery."; - m_discoveryAgent->start(); + + // Since we are only interested in low energy results, this speed up the result significantly + m_discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod); emit discoveringChanged(); } diff --git a/nymea-app/nymea-app.pro b/nymea-app/nymea-app.pro index fa60ddf3..a8604654 100644 --- a/nymea-app/nymea-app.pro +++ b/nymea-app/nymea-app.pro @@ -176,9 +176,8 @@ ios: { OTHER_FILES += $${OBJECTIVE_SOURCES} LIBS += -framework CoreLocation \ - -framework CoreBluetooth \ - -framework CoreNFC - + -framework CoreBluetooth \ + -framework CoreNFC # Add Firebase SDK QMAKE_LFLAGS += -ObjC $(inherited) @@ -186,8 +185,10 @@ ios: { firebase_files.files += $$files($${IOS_PACKAGE_DIR}/GoogleService-Info.plist) QMAKE_BUNDLE_DATA += firebase_files INCLUDEPATH += ../3rdParty/ios/ + LIBS += -F$$PWD/../3rdParty/ios/Firebase/FirebaseAnalytics/ \ -F$$PWD/../3rdParty/ios/Firebase/FirebaseMessaging + LIBS += -framework "FirebaseMessaging" \ -framework "GoogleUtilities" \ -framework "Protobuf" \ @@ -196,13 +197,13 @@ ios: { -framework "FirebaseInstallations" \ -framework "PromisesObjC" \ - LIBS += -L$$top_builddir/libnymea-app -lnymea-app \ - -L$$top_builddir/experiences/airconditioning -lnymea-app-airconditioning \ + -L$$top_builddir/experiences/airconditioning -lnymea-app-airconditioning \ + -L$$top_builddir/experiences/evdash -lnymea-app-evdash PRE_TARGETDEPS += $$top_builddir/libnymea-app/libnymea-app.a \ - $$top_builddir/experiences/airconditioning/libnymea-app-airconditioning.a - + $$top_builddir/experiences/airconditioning/libnymea-app-airconditioning.a \ + $$top_builddir/experiences/evdash/libnymea-app-evdash.a # Configure generated xcode project to have our bundle id QMAKE_TARGET_BUNDLE_PREFIX=$${IOS_BUNDLE_PREFIX} @@ -220,6 +221,9 @@ ios: { ios_launch_images.files += $${IOS_PACKAGE_DIR}/NymeaLaunchScreen.storyboard QMAKE_BUNDLE_DATA += ios_launch_images + DEFINES += QT_STATICPLUGIN + QTPLUGIN += qdarwinbluetoothpermission + IOS_DEVELOPMENT_TEAM.name = DEVELOPMENT_TEAM IOS_DEVELOPMENT_TEAM.value = $$IOS_TEAM_ID QMAKE_MAC_XCODE_SETTINGS += IOS_DEVELOPMENT_TEAM diff --git a/nymea-app/platformintegration/ios/platformpermissionsios.cpp b/nymea-app/platformintegration/ios/platformpermissionsios.cpp index 755c93d6..80efd006 100644 --- a/nymea-app/platformintegration/ios/platformpermissionsios.cpp +++ b/nymea-app/platformintegration/ios/platformpermissionsios.cpp @@ -26,6 +26,11 @@ #include #include +#include +#include + +#include "logging.h" +NYMEA_LOGGING_CATEGORY(dcPlatformPermissions, "PlatformPermissions") PlatformPermissionsIOS *PlatformPermissionsIOS::s_instance = nullptr; @@ -61,13 +66,13 @@ PlatformPermissions::PermissionStatus PlatformPermissionsIOS::checkPermission(Pe case PermissionBluetooth: return checkBluetoothPermission(); default: - return PermissionStatusGranted; + return PermissionStatusGranted; } } -void PlatformPermissionsIOS::requestPermission(Permission permission) +void PlatformPermissionsIOS::requestPermission(Permission platformPermission) { - switch (permission) { + switch (platformPermission) { case PermissionNone: break; case PermissionLocalNetwork: diff --git a/nymea-app/platformintegration/ios/platformpermissionsios.h b/nymea-app/platformintegration/ios/platformpermissionsios.h index 7b847118..fe7bbc47 100644 --- a/nymea-app/platformintegration/ios/platformpermissionsios.h +++ b/nymea-app/platformintegration/ios/platformpermissionsios.h @@ -32,9 +32,11 @@ #if __OBJC__ @class CLLocationManager; @class CBCentralManager; +@class BluetoothManagerDelegate; #else typedef void CLLocationManager; typedef void CBCentralManager; +typedef void BluetoothManagerDelegate; #endif class PlatformPermissionsIOS : public PlatformPermissions @@ -44,8 +46,8 @@ public: explicit PlatformPermissionsIOS(QObject *parent = nullptr); static PlatformPermissionsIOS *instance(); - PermissionStatus checkPermission(Permission permission) const override; - void requestPermission(Permission permission) override; + PermissionStatus checkPermission(Permission ) const override; + void requestPermission(Permission platformPermission) override; void openPermissionSettings() override; private: @@ -62,14 +64,15 @@ private: void requestLocalNetworkPermission(); void requestNotificationPermission(); void requestBluetoothPermission(); + void requestBluetoothPermissionLegacy(); void requestLocationPermission(); void requestBackgroundLocationPermission(); PermissionStatus m_notificationPermissions = PermissionStatusNotDetermined; - CLLocationManager *m_locationManager = nullptr; CBCentralManager *m_bluetoothManager = nullptr; + BluetoothManagerDelegate *m_bluetoothDelegate = nullptr; }; #endif // PLATFORMPERMISSIONSIOS_H diff --git a/nymea-app/platformintegration/ios/platformpermissionsios.mm b/nymea-app/platformintegration/ios/platformpermissionsios.mm index 55129169..a2422c77 100644 --- a/nymea-app/platformintegration/ios/platformpermissionsios.mm +++ b/nymea-app/platformintegration/ios/platformpermissionsios.mm @@ -1,11 +1,25 @@ #include "platformpermissionsios.h" +#include +#include +#include +#include +#include +#include + #import #import #import #import #import +#include "logging.h" +Q_DECLARE_LOGGING_CATEGORY(dcPlatformPermissions) + +#ifdef QT_STATICPLUGIN +Q_IMPORT_PLUGIN(QDarwinBluetoothPermissionPlugin) +#endif + @interface LocationManagerPermissionDelegate : NSObject @end @implementation LocationManagerPermissionDelegate @@ -69,28 +83,112 @@ void PlatformPermissionsIOS::requestNotificationPermission() PlatformPermissions::PermissionStatus PlatformPermissionsIOS::checkBluetoothPermission() const { - // iOS 13.0 would have an api but it's more complicated and also deprecated... Ignoring... + qCDebug(dcPlatformPermissions()) << "Checking bluetooth permission..."; + QBluetoothPermission btPermission; + btPermission.setCommunicationModes(QBluetoothPermission::Access); + const auto qtStatus = qGuiApp->checkPermission(btPermission); + if (qtStatus == Qt::PermissionStatus::Granted) { + qCDebug(dcPlatformPermissions()) << "Bluetooth permisson granted (Qt plugin)"; + return PermissionStatusGranted; + } else { + qCDebug(dcPlatformPermissions()) << "Bluetooth permisson NOT granted (Qt plugin)"; + } + + PermissionStatus fallbackStatus = PermissionStatusGranted; if (@available(iOS 13.1, *)) { switch (CBCentralManager.authorization) { case CBManagerAuthorizationAllowedAlways: + fallbackStatus = PermissionStatusGranted; + break; case CBManagerAuthorizationRestricted: - return PermissionStatusGranted; + fallbackStatus = PermissionStatusGranted; + break; case CBManagerAuthorizationDenied: - return PermissionStatusDenied; + fallbackStatus = PermissionStatusDenied; + break; case CBManagerAuthorizationNotDetermined: - return PermissionStatusNotDetermined; + fallbackStatus = PermissionStatusNotDetermined; + break; } + } else { + // Before iOS 13, Bluetooth permissions are not required + fallbackStatus = PermissionStatusGranted; } - // Before iOS 13, Bluetooth permissions are not required - return PermissionStatusGranted; + + switch (qtStatus) { + case Qt::PermissionStatus::Denied: + qCWarning(dcPlatformPermissions()) << "Bluetooth permission denied by Qt plugin, fallback reports" << fallbackStatus; + break; + case Qt::PermissionStatus::Undetermined: + qCWarning(dcPlatformPermissions()) << "QBluetoothPermission status Undetermined...using fallback."; + break; + case Qt::PermissionStatus::Granted: + break; + } + + return fallbackStatus; } void PlatformPermissionsIOS::requestBluetoothPermission() { - // Instantiating a Bluetooth manager just trigger the popup... + qCDebug(dcPlatformPermissions()) << "Requesting bluetooth permission..."; + auto handlePermissionResult = [](const QPermission &permission) { + switch (permission.status()) { + case Qt::PermissionStatus::Granted: + qCDebug(dcPlatformPermissions()) << "Bluetooth permission granted."; + emit s_instance->bluetoothPermissionChanged(); + return; + case Qt::PermissionStatus::Denied: + if (s_instance->checkBluetoothPermission() == PermissionStatusNotDetermined) { + qCWarning(dcPlatformPermissions()) << "Bluetooth permission plugin unavailable, falling back to CoreBluetooth request."; + s_instance->requestBluetoothPermissionLegacy(); + return; + } + qCWarning(dcPlatformPermissions()) << "Bluetooth permission denied."; + emit s_instance->bluetoothPermissionChanged(); + return; + case Qt::PermissionStatus::Undetermined: + qCWarning(dcPlatformPermissions()) << "Bluetooth permission plugin unavailable, falling back to CoreBluetooth request."; + s_instance->requestBluetoothPermissionLegacy(); + return; + } + }; + + QBluetoothPermission btPermission; + btPermission.setCommunicationModes(QBluetoothPermission::Access); + + if (qApp->checkPermission(btPermission) == Qt::PermissionStatus::Undetermined) { + auto permissionHandled = QSharedPointer::create(false); + + qApp->requestPermission(btPermission, [handlePermissionResult, permissionHandled](const QPermission &permission) { + *permissionHandled = true; + handlePermissionResult(permission); + }); + + // The Qt permission plugin might be missing from certain builds. If we still don't have + // a decision after giving it a moment, fall back to the CoreBluetooth prompt. + QTimer::singleShot(2000, this, [this, permissionHandled]() { + if (*permissionHandled) { + return; + } + if (checkBluetoothPermission() == PermissionStatusNotDetermined) { + qCWarning(dcPlatformPermissions()) << "Bluetooth permission plugin unavailable, falling back to CoreBluetooth request."; + requestBluetoothPermissionLegacy(); + } + }); + return; + } + + handlePermissionResult(btPermission); +} + +void PlatformPermissionsIOS::requestBluetoothPermissionLegacy() +{ + qCDebug(dcPlatformPermissions()) << "Requesting bluetooth permission legacy..."; + // Instantiating a Bluetooth manager triggers the native dialog on first use. if (!m_bluetoothManager) { - BluetoothManagerDelegate *delegate = [[BluetoothManagerDelegate alloc] init]; - m_bluetoothManager = [[CBCentralManager alloc] initWithDelegate:delegate queue:nil]; + m_bluetoothDelegate = [[BluetoothManagerDelegate alloc] init]; + m_bluetoothManager = [[CBCentralManager alloc] initWithDelegate:m_bluetoothDelegate queue:nil]; } } diff --git a/packaging/ios/Info.plist.cmake.in b/packaging/ios/Info.plist.cmake.in index 54c03110..dff7cba0 100644 --- a/packaging/ios/Info.plist.cmake.in +++ b/packaging/ios/Info.plist.cmake.in @@ -48,6 +48,14 @@ _jsonrpc._tcp _ws._tcp + NSAppTransportSecurity + + + NSAllowsArbitraryLoads + + NSAllowsLocalNetworking + + UIViewControllerBasedStatusBarAppearance XSAppIconAssets diff --git a/version.txt b/version.txt index 82cfbbbb..490dd04c 100644 --- a/version.txt +++ b/version.txt @@ -1,2 +1,2 @@ 1.11.1 -687 +689 From b4a4f993ff82421c88f762446ab87fa12276d05e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Fri, 12 Dec 2025 15:28:35 +0100 Subject: [PATCH 49/50] Restore favorites and groups mechanism --- libnymea-app/models/tagsproxymodel.cpp | 2 +- libnymea-app/tagsmanager.cpp | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/libnymea-app/models/tagsproxymodel.cpp b/libnymea-app/models/tagsproxymodel.cpp index a8d10ae9..df31f306 100644 --- a/libnymea-app/models/tagsproxymodel.cpp +++ b/libnymea-app/models/tagsproxymodel.cpp @@ -145,7 +145,7 @@ bool TagsProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_ qCDebug(dcTags) << "Filter: ID:" << m_filterTagId << "Thing:" << m_filterThingId << "value:" << m_filterValue; if (!m_filterTagId.isEmpty()) { QRegularExpression exp(m_filterTagId); - if (exp.match(tag->tagId()).hasMatch()) { + if (!exp.match(tag->tagId()).hasMatch()) { return false; } } diff --git a/libnymea-app/tagsmanager.cpp b/libnymea-app/tagsmanager.cpp index 3835f734..8a01038d 100644 --- a/libnymea-app/tagsmanager.cpp +++ b/libnymea-app/tagsmanager.cpp @@ -150,7 +150,11 @@ void TagsManager::getTagsResponse(int /*commandId*/, const QVariantMap ¶ms) { QList tags; foreach (const QVariant &tagVariant, params.value("tags").toList()) { - Tag *tag = unpackTag(tagVariant.toMap()); + QVariantMap tagMap = tagVariant.toMap(); + if (tagMap.value("appId").toString() != "nymea:app") { + continue; + } + Tag *tag = unpackTag(tagMap); if (tag) { tags.append(tag); } From 1151166f9224fe6f2130ae81bd239ba73b8e4e0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Fri, 12 Dec 2025 16:14:58 +0100 Subject: [PATCH 50/50] Update revision --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 490dd04c..e5daaf8f 100644 --- a/version.txt +++ b/version.txt @@ -1,2 +1,2 @@ 1.11.1 -689 +691