Merge PR #285: Implement new system time api
This commit is contained in:
commit
13343bf04e
@ -32,8 +32,6 @@ void NymeaConfiguration::init()
|
|||||||
m_webSocketServerConfigurations->clear();
|
m_webSocketServerConfigurations->clear();
|
||||||
m_mqttServerConfigurations->clear();
|
m_mqttServerConfigurations->clear();
|
||||||
m_client->sendCommand("Configuration.GetConfigurations", this, "getConfigurationsResponse");
|
m_client->sendCommand("Configuration.GetConfigurations", this, "getConfigurationsResponse");
|
||||||
m_client->sendCommand("Configuration.GetAvailableLanguages", this, "getAvailableLanguagesResponse");
|
|
||||||
m_client->sendCommand("Configuration.GetTimeZones", this, "getTimezonesResponse");
|
|
||||||
m_client->sendCommand("Configuration.GetMqttServerConfigurations", this, "getMqttServerConfigsReply");
|
m_client->sendCommand("Configuration.GetMqttServerConfigurations", this, "getMqttServerConfigsReply");
|
||||||
m_client->sendCommand("Configuration.GetMqttPolicies", this, "getMqttPoliciesReply");
|
m_client->sendCommand("Configuration.GetMqttPolicies", this, "getMqttPoliciesReply");
|
||||||
}
|
}
|
||||||
@ -50,38 +48,11 @@ void NymeaConfiguration::setServerName(const QString &serverName)
|
|||||||
m_client->sendCommand("Configuration.SetServerName", params, this, "setServerNameResponse");
|
m_client->sendCommand("Configuration.SetServerName", params, this, "setServerNameResponse");
|
||||||
}
|
}
|
||||||
|
|
||||||
QString NymeaConfiguration::language() const
|
|
||||||
{
|
|
||||||
return m_language;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NymeaConfiguration::setLanguage(const QString &language)
|
|
||||||
{
|
|
||||||
QVariantMap params;
|
|
||||||
params.insert("language", language);
|
|
||||||
m_client->sendCommand("Configuration.SetLanguage", params);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList NymeaConfiguration::availableLanguages() const
|
|
||||||
{
|
|
||||||
return m_availableLanguages;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString NymeaConfiguration::timezone() const
|
|
||||||
{
|
|
||||||
return m_timezone;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NymeaConfiguration::setTimezone(const QString &timezone)
|
void NymeaConfiguration::setTimezone(const QString &timezone)
|
||||||
{
|
{
|
||||||
QVariantMap params;
|
QVariantMap params;
|
||||||
params.insert("timeZone", timezone);
|
params.insert("timeZone", timezone);
|
||||||
m_client->sendCommand("Configuration.SetTimeZone", params, this, "setTimezoneResponse");
|
m_client->sendCommand("System.SetTimeZone", params, this, "setTimezoneResponse");
|
||||||
}
|
|
||||||
|
|
||||||
QStringList NymeaConfiguration::timezones() const
|
|
||||||
{
|
|
||||||
return m_timezones;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NymeaConfiguration::debugServerEnabled() const
|
bool NymeaConfiguration::debugServerEnabled() const
|
||||||
@ -259,10 +230,6 @@ void NymeaConfiguration::getConfigurationsResponse(const QVariantMap ¶ms)
|
|||||||
emit debugServerEnabledChanged();
|
emit debugServerEnabledChanged();
|
||||||
m_serverName = basicConfig.value("serverName").toString();
|
m_serverName = basicConfig.value("serverName").toString();
|
||||||
emit serverNameChanged();
|
emit serverNameChanged();
|
||||||
m_language = basicConfig.value("language").toString();
|
|
||||||
emit languageChanged();
|
|
||||||
m_timezone = basicConfig.value("timeZone").toString();
|
|
||||||
emit timezoneChanged();
|
|
||||||
QVariantMap cloudConfig = params.value("params").toMap().value("cloud").toMap();
|
QVariantMap cloudConfig = params.value("params").toMap().value("cloud").toMap();
|
||||||
m_cloudEnabled = cloudConfig.value("enabled").toBool();
|
m_cloudEnabled = cloudConfig.value("enabled").toBool();
|
||||||
emit cloudEnabledChanged();
|
emit cloudEnabledChanged();
|
||||||
@ -290,25 +257,6 @@ void NymeaConfiguration::getConfigurationsResponse(const QVariantMap ¶ms)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NymeaConfiguration::getAvailableLanguagesResponse(const QVariantMap ¶ms)
|
|
||||||
{
|
|
||||||
// qDebug() << "available languages" << params;
|
|
||||||
m_availableLanguages = params.value("params").toMap().value("languages").toStringList();
|
|
||||||
emit availableLanguagesChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NymeaConfiguration::getTimezonesResponse(const QVariantMap ¶ms)
|
|
||||||
{
|
|
||||||
// qDebug() << "Get timezones response" << params;
|
|
||||||
m_timezones = params.value("params").toMap().value("timeZones").toStringList();
|
|
||||||
emit timezonesChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NymeaConfiguration::setTimezoneResponse(const QVariantMap ¶ms)
|
|
||||||
{
|
|
||||||
qDebug() << "Set timezones response" << params;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NymeaConfiguration::setServerNameResponse(const QVariantMap ¶ms)
|
void NymeaConfiguration::setServerNameResponse(const QVariantMap ¶ms)
|
||||||
{
|
{
|
||||||
qDebug() << "Server name set:" << params;
|
qDebug() << "Server name set:" << params;
|
||||||
@ -416,10 +364,6 @@ void NymeaConfiguration::notificationReceived(const QVariantMap ¬ification)
|
|||||||
emit debugServerEnabledChanged();
|
emit debugServerEnabledChanged();
|
||||||
m_serverName = params.value("serverName").toString();
|
m_serverName = params.value("serverName").toString();
|
||||||
emit serverNameChanged();
|
emit serverNameChanged();
|
||||||
m_language = params.value("language").toString();
|
|
||||||
emit languageChanged();
|
|
||||||
m_timezone = params.value("timeZone").toString();
|
|
||||||
emit timezoneChanged();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (notif == "Configuration.CloudConfigurationChanged") {
|
if (notif == "Configuration.CloudConfigurationChanged") {
|
||||||
|
|||||||
@ -19,12 +19,6 @@ class NymeaConfiguration : public JsonHandler
|
|||||||
|
|
||||||
Q_PROPERTY(QString serverName READ serverName WRITE setServerName NOTIFY serverNameChanged)
|
Q_PROPERTY(QString serverName READ serverName WRITE setServerName NOTIFY serverNameChanged)
|
||||||
|
|
||||||
Q_PROPERTY(QString language READ language WRITE setLanguage NOTIFY languageChanged)
|
|
||||||
Q_PROPERTY(QStringList availableLanguages READ availableLanguages NOTIFY availableLanguagesChanged)
|
|
||||||
|
|
||||||
Q_PROPERTY(QString timezone READ timezone WRITE setTimezone NOTIFY timezoneChanged)
|
|
||||||
Q_PROPERTY(QStringList timezones READ timezones NOTIFY timezonesChanged)
|
|
||||||
|
|
||||||
Q_PROPERTY(bool cloudEnabled READ cloudEnabled WRITE setCloudEnabled NOTIFY cloudEnabledChanged)
|
Q_PROPERTY(bool cloudEnabled READ cloudEnabled WRITE setCloudEnabled NOTIFY cloudEnabledChanged)
|
||||||
Q_PROPERTY(bool debugServerEnabled READ debugServerEnabled WRITE setDebugServerEnabled NOTIFY debugServerEnabledChanged)
|
Q_PROPERTY(bool debugServerEnabled READ debugServerEnabled WRITE setDebugServerEnabled NOTIFY debugServerEnabledChanged)
|
||||||
|
|
||||||
@ -87,9 +81,6 @@ private:
|
|||||||
Q_INVOKABLE void setDebugServerEnabledResponse(const QVariantMap ¶ms);
|
Q_INVOKABLE void setDebugServerEnabledResponse(const QVariantMap ¶ms);
|
||||||
Q_INVOKABLE void setServerNameResponse(const QVariantMap ¶ms);
|
Q_INVOKABLE void setServerNameResponse(const QVariantMap ¶ms);
|
||||||
Q_INVOKABLE void setCloudEnabledResponse(const QVariantMap ¶ms);
|
Q_INVOKABLE void setCloudEnabledResponse(const QVariantMap ¶ms);
|
||||||
Q_INVOKABLE void getAvailableLanguagesResponse(const QVariantMap ¶ms);
|
|
||||||
Q_INVOKABLE void getTimezonesResponse(const QVariantMap ¶ms);
|
|
||||||
Q_INVOKABLE void setTimezoneResponse(const QVariantMap ¶ms);
|
|
||||||
Q_INVOKABLE void setTcpConfigReply(const QVariantMap ¶ms);
|
Q_INVOKABLE void setTcpConfigReply(const QVariantMap ¶ms);
|
||||||
Q_INVOKABLE void deleteTcpConfigReply(const QVariantMap ¶ms);
|
Q_INVOKABLE void deleteTcpConfigReply(const QVariantMap ¶ms);
|
||||||
Q_INVOKABLE void setWebSocketConfigReply(const QVariantMap ¶ms);
|
Q_INVOKABLE void setWebSocketConfigReply(const QVariantMap ¶ms);
|
||||||
@ -108,10 +99,6 @@ private:
|
|||||||
signals:
|
signals:
|
||||||
void debugServerEnabledChanged();
|
void debugServerEnabledChanged();
|
||||||
void serverNameChanged();
|
void serverNameChanged();
|
||||||
void languageChanged();
|
|
||||||
void availableLanguagesChanged();
|
|
||||||
void timezoneChanged();
|
|
||||||
void timezonesChanged();
|
|
||||||
void cloudEnabledChanged();
|
void cloudEnabledChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -119,10 +106,6 @@ private:
|
|||||||
|
|
||||||
bool m_debugServerEnabled = false;
|
bool m_debugServerEnabled = false;
|
||||||
QString m_serverName;
|
QString m_serverName;
|
||||||
QString m_language;
|
|
||||||
QStringList m_availableLanguages;
|
|
||||||
QString m_timezone;
|
|
||||||
QStringList m_timezones;
|
|
||||||
bool m_cloudEnabled = false;
|
bool m_cloudEnabled = false;
|
||||||
|
|
||||||
ServerConfigurations *m_tcpServerConfigurations = nullptr;
|
ServerConfigurations *m_tcpServerConfigurations = nullptr;
|
||||||
|
|||||||
@ -5,6 +5,8 @@
|
|||||||
#include "types/packages.h"
|
#include "types/packages.h"
|
||||||
#include "types/repositories.h"
|
#include "types/repositories.h"
|
||||||
|
|
||||||
|
#include <QTimeZone>
|
||||||
|
|
||||||
SystemController::SystemController(JsonRpcClient *jsonRpcClient, QObject *parent):
|
SystemController::SystemController(JsonRpcClient *jsonRpcClient, QObject *parent):
|
||||||
JsonHandler(parent),
|
JsonHandler(parent),
|
||||||
m_jsonRpcClient(jsonRpcClient)
|
m_jsonRpcClient(jsonRpcClient)
|
||||||
@ -12,6 +14,8 @@ SystemController::SystemController(JsonRpcClient *jsonRpcClient, QObject *parent
|
|||||||
m_jsonRpcClient->registerNotificationHandler(this, "notificationReceived");
|
m_jsonRpcClient->registerNotificationHandler(this, "notificationReceived");
|
||||||
m_packages = new Packages(this);
|
m_packages = new Packages(this);
|
||||||
m_repositories = new Repositories(this);
|
m_repositories = new Repositories(this);
|
||||||
|
|
||||||
|
startTimer(1000, Qt::VeryCoarseTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemController::init()
|
void SystemController::init()
|
||||||
@ -22,6 +26,8 @@ void SystemController::init()
|
|||||||
m_jsonRpcClient->sendCommand("System.GetCapabilities", this, "getCapabilitiesResponse");
|
m_jsonRpcClient->sendCommand("System.GetCapabilities", this, "getCapabilitiesResponse");
|
||||||
} else {
|
} else {
|
||||||
m_powerManagementAvailable = false;
|
m_powerManagementAvailable = false;
|
||||||
|
m_updateManagementAvailable = false;
|
||||||
|
m_timeManagementAvailable = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,6 +107,63 @@ int SystemController::enableRepository(const QString &id, bool enabled)
|
|||||||
return m_jsonRpcClient->sendCommand("System.EnableRepository", params, this, "enableRepositoryResponse");
|
return m_jsonRpcClient->sendCommand("System.EnableRepository", params, this, "enableRepositoryResponse");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SystemController::timeManagementAvailable() const
|
||||||
|
{
|
||||||
|
return m_timeManagementAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDateTime SystemController::serverTime() const
|
||||||
|
{
|
||||||
|
return m_serverTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemController::setServerTime(const QDateTime &serverTime)
|
||||||
|
{
|
||||||
|
QVariantMap params;
|
||||||
|
params.insert("automaticTime", false);
|
||||||
|
params.insert("time", serverTime.toSecsSinceEpoch());
|
||||||
|
params.insert("timeZone", serverTime.timeZone().id());
|
||||||
|
m_jsonRpcClient->sendCommand("System.SetTime", params, this, "setTimeResponse");
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList SystemController::timeZones() const
|
||||||
|
{
|
||||||
|
QStringList ret;
|
||||||
|
foreach (const QByteArray &tzId, QTimeZone::availableTimeZoneIds()) {
|
||||||
|
ret << tzId;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SystemController::serverTimeZone() const
|
||||||
|
{
|
||||||
|
return m_serverTime.timeZone().id();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemController::setServerTimeZone(const QString &serverTimeZone)
|
||||||
|
{
|
||||||
|
QVariantMap params;
|
||||||
|
params.insert("timeZone", serverTimeZone);
|
||||||
|
m_jsonRpcClient->sendCommand("System.SetTime", params, this, "setTimeResponse");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SystemController::automaticTimeAvailable() const
|
||||||
|
{
|
||||||
|
return m_automaticTimeAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SystemController::automaticTime() const
|
||||||
|
{
|
||||||
|
return m_automaticTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemController::setAutomaticTime(bool automaticTime)
|
||||||
|
{
|
||||||
|
QVariantMap params;
|
||||||
|
params.insert("automaticTime", automaticTime);
|
||||||
|
m_jsonRpcClient->sendCommand("System.SetTime", params, this, "setTimeResponse");
|
||||||
|
}
|
||||||
|
|
||||||
void SystemController::getCapabilitiesResponse(const QVariantMap &data)
|
void SystemController::getCapabilitiesResponse(const QVariantMap &data)
|
||||||
{
|
{
|
||||||
qDebug() << "capabilities received" << data;
|
qDebug() << "capabilities received" << data;
|
||||||
@ -110,11 +173,18 @@ void SystemController::getCapabilitiesResponse(const QVariantMap &data)
|
|||||||
m_updateManagementAvailable = data.value("params").toMap().value("updateManagement").toBool();
|
m_updateManagementAvailable = data.value("params").toMap().value("updateManagement").toBool();
|
||||||
emit updateManagementAvailableChanged();
|
emit updateManagementAvailableChanged();
|
||||||
|
|
||||||
|
m_timeManagementAvailable = data.value("params").toMap().value("timeManagement").toBool();
|
||||||
|
emit timeManagementAvailableChanged();
|
||||||
|
|
||||||
if (m_updateManagementAvailable) {
|
if (m_updateManagementAvailable) {
|
||||||
m_jsonRpcClient->sendCommand("System.GetUpdateStatus", this, "getUpdateStatusResponse");
|
m_jsonRpcClient->sendCommand("System.GetUpdateStatus", this, "getUpdateStatusResponse");
|
||||||
m_jsonRpcClient->sendCommand("System.GetPackages", this, "getPackagesResponse");
|
m_jsonRpcClient->sendCommand("System.GetPackages", this, "getPackagesResponse");
|
||||||
m_jsonRpcClient->sendCommand("System.GetRepositories", this, "getRepositoriesResponse");
|
m_jsonRpcClient->sendCommand("System.GetRepositories", this, "getRepositoriesResponse");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (m_jsonRpcClient->ensureServerVersion("4.1")) {
|
||||||
|
m_jsonRpcClient->sendCommand("System.GetTime", this, "getServerTimeResponse");
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemController::getUpdateStatusResponse(const QVariantMap &data)
|
void SystemController::getUpdateStatusResponse(const QVariantMap &data)
|
||||||
@ -164,6 +234,24 @@ void SystemController::enableRepositoryResponse(const QVariantMap ¶ms)
|
|||||||
emit enableRepositoryFinished(params.value("id").toInt(), params.value("params").toMap().value("success").toBool());
|
emit enableRepositoryFinished(params.value("id").toInt(), params.value("params").toMap().value("success").toBool());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SystemController::getServerTimeResponse(const QVariantMap ¶ms)
|
||||||
|
{
|
||||||
|
qDebug() << "Server time" << params;
|
||||||
|
m_serverTime = QDateTime::fromSecsSinceEpoch(params.value("params").toMap().value("time").toUInt());
|
||||||
|
m_serverTime.setTimeZone(QTimeZone(params.value("params").toMap().value("timeZone").toString().toUtf8()));
|
||||||
|
emit serverTimeChanged();
|
||||||
|
emit serverTimeZoneChanged();
|
||||||
|
m_automaticTimeAvailable = params.value("params").toMap().value("automaticTimeAvailable").toBool();
|
||||||
|
emit automaticTimeAvailableChanged();
|
||||||
|
m_automaticTime = params.value("params").toMap().value("automaticTime").toBool();
|
||||||
|
emit automaticTimeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemController::setTimeResponse(const QVariantMap ¶ms)
|
||||||
|
{
|
||||||
|
qDebug() << "set time response" << params;
|
||||||
|
}
|
||||||
|
|
||||||
void SystemController::notificationReceived(const QVariantMap &data)
|
void SystemController::notificationReceived(const QVariantMap &data)
|
||||||
{
|
{
|
||||||
QString notification = data.value("notification").toString();
|
QString notification = data.value("notification").toString();
|
||||||
@ -233,7 +321,24 @@ void SystemController::notificationReceived(const QVariantMap &data)
|
|||||||
qWarning() << "System capabilites changed: power management:" << m_powerManagementAvailable << "update management:" << m_updateManagementAvailable;
|
qWarning() << "System capabilites changed: power management:" << m_powerManagementAvailable << "update management:" << m_updateManagementAvailable;
|
||||||
emit powerManagementAvailableChanged();
|
emit powerManagementAvailableChanged();
|
||||||
emit updateManagementAvailableChanged();
|
emit updateManagementAvailableChanged();
|
||||||
|
} else if (notification == "System.TimeConfigurationChanged") {
|
||||||
|
qDebug() << "System time configuration changed";
|
||||||
|
m_serverTime = QDateTime::fromSecsSinceEpoch(data.value("params").toMap().value("time").toUInt());
|
||||||
|
m_serverTime.setTimeZone(QTimeZone(data.value("params").toMap().value("timeZone").toByteArray()));
|
||||||
|
emit serverTimeChanged();
|
||||||
|
emit serverTimeZoneChanged();
|
||||||
|
m_automaticTimeAvailable = data.value("params").toMap().value("automaticTimeAvailable").toBool();
|
||||||
|
emit automaticTimeAvailableChanged();
|
||||||
|
m_automaticTime = data.value("params").toMap().value("automaticTime").toBool();
|
||||||
|
emit automaticTimeChanged();
|
||||||
} else {
|
} else {
|
||||||
qWarning() << "Unhandled System Notification" << data.value("notification");
|
qWarning() << "Unhandled System Notification" << data.value("notification");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SystemController::timerEvent(QTimerEvent *event)
|
||||||
|
{
|
||||||
|
Q_UNUSED(event)
|
||||||
|
m_serverTime = m_serverTime.addSecs(1);
|
||||||
|
emit serverTimeChanged();
|
||||||
|
}
|
||||||
|
|||||||
@ -14,12 +14,19 @@ class SystemController : public JsonHandler
|
|||||||
Q_PROPERTY(bool powerManagementAvailable READ powerManagementAvailable NOTIFY powerManagementAvailableChanged)
|
Q_PROPERTY(bool powerManagementAvailable READ powerManagementAvailable NOTIFY powerManagementAvailableChanged)
|
||||||
// Whether the update mechanism is available in the connected core
|
// Whether the update mechanism is available in the connected core
|
||||||
Q_PROPERTY(bool updateManagementAvailable READ updateManagementAvailable NOTIFY updateManagementAvailableChanged)
|
Q_PROPERTY(bool updateManagementAvailable READ updateManagementAvailable NOTIFY updateManagementAvailableChanged)
|
||||||
|
Q_PROPERTY(bool timeManagementAvailable READ timeManagementAvailable NOTIFY timeManagementAvailableChanged)
|
||||||
|
|
||||||
Q_PROPERTY(bool updateManagementBusy READ updateManagementBusy NOTIFY updateManagementBusyChanged)
|
Q_PROPERTY(bool updateManagementBusy READ updateManagementBusy NOTIFY updateManagementBusyChanged)
|
||||||
Q_PROPERTY(bool updateRunning READ updateRunning NOTIFY updateRunningChanged)
|
Q_PROPERTY(bool updateRunning READ updateRunning NOTIFY updateRunningChanged)
|
||||||
Q_PROPERTY(Packages* packages READ packages CONSTANT)
|
Q_PROPERTY(Packages* packages READ packages CONSTANT)
|
||||||
Q_PROPERTY(Repositories* repositories READ repositories CONSTANT)
|
Q_PROPERTY(Repositories* repositories READ repositories CONSTANT)
|
||||||
|
|
||||||
|
Q_PROPERTY(QDateTime serverTime READ serverTime WRITE setServerTime NOTIFY serverTimeChanged)
|
||||||
|
Q_PROPERTY(QString serverTimeZone READ serverTimeZone WRITE setServerTimeZone NOTIFY serverTimeZoneChanged)
|
||||||
|
Q_PROPERTY(QStringList timeZones READ timeZones CONSTANT)
|
||||||
|
Q_PROPERTY(bool automaticTimeAvailable READ automaticTimeAvailable NOTIFY automaticTimeAvailableChanged)
|
||||||
|
Q_PROPERTY(bool automaticTime READ automaticTime WRITE setAutomaticTime NOTIFY automaticTimeChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SystemController(JsonRpcClient *jsonRpcClient, QObject *parent = nullptr);
|
explicit SystemController(JsonRpcClient *jsonRpcClient, QObject *parent = nullptr);
|
||||||
|
|
||||||
@ -27,29 +34,40 @@ public:
|
|||||||
QString nameSpace() const override;
|
QString nameSpace() const override;
|
||||||
|
|
||||||
bool powerManagementAvailable() const;
|
bool powerManagementAvailable() const;
|
||||||
bool updateManagementAvailable() const;
|
|
||||||
|
|
||||||
Q_INVOKABLE void reboot();
|
Q_INVOKABLE void reboot();
|
||||||
Q_INVOKABLE void shutdown();
|
Q_INVOKABLE void shutdown();
|
||||||
|
|
||||||
|
bool updateManagementAvailable() const;
|
||||||
bool updateManagementBusy() const;
|
bool updateManagementBusy() const;
|
||||||
bool updateRunning() const;
|
bool updateRunning() const;
|
||||||
|
|
||||||
Q_INVOKABLE void checkForUpdates();
|
Q_INVOKABLE void checkForUpdates();
|
||||||
Packages* packages() const;
|
Packages* packages() const;
|
||||||
Q_INVOKABLE void updatePackages(const QString packageId = QString());
|
Q_INVOKABLE void updatePackages(const QString packageId = QString());
|
||||||
Q_INVOKABLE void removePackages(const QString packageId = QString());
|
Q_INVOKABLE void removePackages(const QString packageId = QString());
|
||||||
|
|
||||||
Repositories* repositories() const;
|
Repositories* repositories() const;
|
||||||
Q_INVOKABLE int enableRepository(const QString &id, bool enabled);
|
Q_INVOKABLE int enableRepository(const QString &id, bool enabled);
|
||||||
|
|
||||||
|
bool timeManagementAvailable() const;
|
||||||
|
QDateTime serverTime() const;
|
||||||
|
void setServerTime(const QDateTime &serverTime);
|
||||||
|
QStringList timeZones() const;
|
||||||
|
QString serverTimeZone() const;
|
||||||
|
void setServerTimeZone(const QString &serverTimeZone);
|
||||||
|
bool automaticTimeAvailable() const;
|
||||||
|
bool automaticTime() const;
|
||||||
|
void setAutomaticTime(bool automaticTime);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void powerManagementAvailableChanged();
|
void powerManagementAvailableChanged();
|
||||||
void updateManagementAvailableChanged();
|
void updateManagementAvailableChanged();
|
||||||
|
void timeManagementAvailableChanged();
|
||||||
void updateManagementBusyChanged();
|
void updateManagementBusyChanged();
|
||||||
void updateRunningChanged();
|
void updateRunningChanged();
|
||||||
void enableRepositoryFinished(int id, bool success);
|
void enableRepositoryFinished(int id, bool success);
|
||||||
|
void serverTimeChanged();
|
||||||
|
void serverTimeZoneChanged();
|
||||||
|
void automaticTimeAvailableChanged();
|
||||||
|
void automaticTimeChanged();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void getCapabilitiesResponse(const QVariantMap &data);
|
void getCapabilitiesResponse(const QVariantMap &data);
|
||||||
@ -58,19 +76,31 @@ private slots:
|
|||||||
void getRepositoriesResponse(const QVariantMap &data);
|
void getRepositoriesResponse(const QVariantMap &data);
|
||||||
void removePackageResponse(const QVariantMap ¶ms);
|
void removePackageResponse(const QVariantMap ¶ms);
|
||||||
void enableRepositoryResponse(const QVariantMap ¶ms);
|
void enableRepositoryResponse(const QVariantMap ¶ms);
|
||||||
|
void getServerTimeResponse(const QVariantMap ¶ms);
|
||||||
|
void setTimeResponse(const QVariantMap ¶ms);
|
||||||
|
|
||||||
void notificationReceived(const QVariantMap &data);
|
void notificationReceived(const QVariantMap &data);
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void timerEvent(QTimerEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
JsonRpcClient *m_jsonRpcClient = nullptr;
|
JsonRpcClient *m_jsonRpcClient = nullptr;
|
||||||
|
|
||||||
bool m_powerManagementAvailable = false;
|
bool m_powerManagementAvailable = false;
|
||||||
bool m_updateManagementAvailable = false;
|
bool m_updateManagementAvailable = false;
|
||||||
|
bool m_timeManagementAvailable = false;
|
||||||
|
|
||||||
bool m_updateManagementBusy = false;
|
bool m_updateManagementBusy = false;
|
||||||
bool m_updateRunning = false;
|
bool m_updateRunning = false;
|
||||||
Packages *m_packages = nullptr;
|
Packages *m_packages = nullptr;
|
||||||
Repositories *m_repositories = nullptr;
|
Repositories *m_repositories = nullptr;
|
||||||
|
|
||||||
|
QDateTime m_serverTime;
|
||||||
|
QStringList m_timeZones;
|
||||||
|
bool m_automaticTimeAvailable = false;
|
||||||
|
bool m_automaticTime = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SYSTEMCONTROLLER_H
|
#endif // SYSTEMCONTROLLER_H
|
||||||
|
|||||||
@ -80,7 +80,7 @@ void PlatformHelperAndroid::vibrate(PlatformHelper::HapticsFeedback feedbackType
|
|||||||
int duration;
|
int duration;
|
||||||
switch (feedbackType) {
|
switch (feedbackType) {
|
||||||
case HapticsFeedbackSelection:
|
case HapticsFeedbackSelection:
|
||||||
duration = 20;
|
duration = 10;
|
||||||
break;
|
break;
|
||||||
case HapticsFeedbackImpact:
|
case HapticsFeedbackImpact:
|
||||||
duration = 30;
|
duration = 30;
|
||||||
|
|||||||
@ -201,5 +201,7 @@
|
|||||||
<file>ui/mainviews/GroupsView.qml</file>
|
<file>ui/mainviews/GroupsView.qml</file>
|
||||||
<file>ui/grouping/GroupPage.qml</file>
|
<file>ui/grouping/GroupPage.qml</file>
|
||||||
<file>ui/delegates/ThingTile.qml</file>
|
<file>ui/delegates/ThingTile.qml</file>
|
||||||
|
<file>ui/components/TimePicker.qml</file>
|
||||||
|
<file>ui/components/DatePicker.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
134
nymea-app/ui/components/DatePicker.qml
Normal file
134
nymea-app/ui/components/DatePicker.qml
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
import QtQuick 2.3
|
||||||
|
import QtQuick.Controls 2.1
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import Nymea 1.0
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property date date
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
ColorIcon {
|
||||||
|
Layout.preferredHeight: app.iconSize
|
||||||
|
Layout.preferredWidth: app.iconSize
|
||||||
|
name: "../images/back.svg"
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
var newDate = new Date(root.date)
|
||||||
|
newDate.setMonth(root.date.getMonth() - 1)
|
||||||
|
root.date = newDate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: root.date.toLocaleDateString()
|
||||||
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
ColorIcon {
|
||||||
|
Layout.preferredHeight: app.iconSize
|
||||||
|
Layout.preferredWidth: app.iconSize
|
||||||
|
name: "../images/next.svg"
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
var newDate = new Date(root.date)
|
||||||
|
newDate.setMonth(root.date.getMonth() + 1)
|
||||||
|
root.date = newDate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ThinDivider {}
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: monthModel
|
||||||
|
ListElement { text: qsTr("January"); days: 31; leapYearDays: 31 }
|
||||||
|
ListElement { text: qsTr("February"); days: 28; leapYearDays: 29 }
|
||||||
|
ListElement { text: qsTr("March"); days: 31; leapYearDays: 31 }
|
||||||
|
ListElement { text: qsTr("April"); days: 30; leapYearDays: 30 }
|
||||||
|
ListElement { text: qsTr("May"); days: 31; leapYearDays: 31 }
|
||||||
|
ListElement { text: qsTr("June"); days: 30; leapYearDays: 30 }
|
||||||
|
ListElement { text: qsTr("July"); days: 31; leapYearDays: 31 }
|
||||||
|
ListElement { text: qsTr("August"); days: 31; leapYearDays: 31 }
|
||||||
|
ListElement { text: qsTr("September"); days: 30; leapYearDays: 30 }
|
||||||
|
ListElement { text: qsTr("October"); days: 31; leapYearDays: 31 }
|
||||||
|
ListElement { text: qsTr("November"); days: 30; leapYearDays: 30 }
|
||||||
|
ListElement { text: qsTr("December"); days: 31; leapYearDays: 31 }
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: weekModel
|
||||||
|
ListElement { text: qsTr("Mon") }
|
||||||
|
ListElement { text: qsTr("Tue") }
|
||||||
|
ListElement { text: qsTr("Wed") }
|
||||||
|
ListElement { text: qsTr("Thu") }
|
||||||
|
ListElement { text: qsTr("Fri") }
|
||||||
|
ListElement { text: qsTr("Sat") }
|
||||||
|
ListElement { text: qsTr("Sun") }
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Repeater {
|
||||||
|
model: weekModel
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: width
|
||||||
|
Label {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: model.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
id: daysGrid
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
columns: 7
|
||||||
|
columnSpacing: 0
|
||||||
|
rowSpacing: 0
|
||||||
|
|
||||||
|
property date firstOfMonth: new Date(root.date.getFullYear(), root.date.getMonth(), 1)
|
||||||
|
property int offset: ((firstOfMonth.getDay() - 1) % 7 + 7) % 7
|
||||||
|
property bool isLeapYear: firstOfMonth.getFullYear() % 4 == 0 && firstOfMonth.getFullYear() % 100 != 0
|
||||||
|
property int daysInMonth: isLeapYear ? monthModel.get(root.date.getMonth()).leapYearDays : monthModel.get(root.date.getMonth()).days
|
||||||
|
property int daysInPreviousMonth: isLeapYear ? monthModel.get((root.date.getMonth() + 11) % 12).leapYearDays : monthModel.get((root.date.getMonth() + 11) % 12).days
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: 6 * 7
|
||||||
|
|
||||||
|
delegate: Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: width
|
||||||
|
radius: width / 2
|
||||||
|
property int dayOfMonth: index - daysGrid.offset + 1
|
||||||
|
property bool isPreviousMonth: dayOfMonth < 1
|
||||||
|
property bool isNextMonth: dayOfMonth > daysGrid.daysInMonth
|
||||||
|
property int correctedDayOfMonth: isPreviousMonth ? daysGrid.daysInPreviousMonth + dayOfMonth
|
||||||
|
: isNextMonth ? dayOfMonth - daysGrid.daysInMonth : dayOfMonth
|
||||||
|
color: !isPreviousMonth && !isNextMonth && correctedDayOfMonth == root.date.getDate() ? app.accentColor : "transparent"
|
||||||
|
Label {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
opacity: isPreviousMonth || isNextMonth ? 0.6 : 1
|
||||||
|
|
||||||
|
text: correctedDayOfMonth
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
var newDate = new Date(root.date)
|
||||||
|
newDate.setDate(dayOfMonth)
|
||||||
|
root.date = newDate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
261
nymea-app/ui/components/TimePicker.qml
Normal file
261
nymea-app/ui/components/TimePicker.qml
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
import QtQuick 2.3
|
||||||
|
import QtQuick.Controls 2.1
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import Nymea 1.0
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: root
|
||||||
|
spacing: app.margins
|
||||||
|
|
||||||
|
property int hour: 0
|
||||||
|
property int minute: 0
|
||||||
|
|
||||||
|
function selectHours() {
|
||||||
|
d.mode = "hours"
|
||||||
|
}
|
||||||
|
function selectMinutes() {
|
||||||
|
d.mode = "minutes"
|
||||||
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
initTimer.start();
|
||||||
|
}
|
||||||
|
Timer {
|
||||||
|
id: initTimer
|
||||||
|
interval: 1
|
||||||
|
onTriggered: selectHours();
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Label {
|
||||||
|
text: app.pad(root.hour, 2)
|
||||||
|
font.pixelSize: app.largeFont * 2
|
||||||
|
opacity: d.mode == "hours" ? 1 : .6
|
||||||
|
Behavior on opacity { NumberAnimation {duration: 250 } }
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: selectHours()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: ":"
|
||||||
|
font.pixelSize: app.largeFont * 2
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: app.pad(root.minute, 2)
|
||||||
|
font.pixelSize: app.largeFont * 2
|
||||||
|
opacity: d.mode == "minutes" ? 1 : .6
|
||||||
|
Behavior on opacity { NumberAnimation {duration: 250 } }
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: selectMinutes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: d
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: width
|
||||||
|
|
||||||
|
property string mode: "none"
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: dial
|
||||||
|
height: Math.min(parent.height, parent.width)
|
||||||
|
width: height
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: hours12
|
||||||
|
|
||||||
|
model: 12
|
||||||
|
delegate: Item {
|
||||||
|
id: delegate
|
||||||
|
visible: d.mode == "hours"
|
||||||
|
anchors.centerIn: parent
|
||||||
|
height: parent.height
|
||||||
|
rotation: (360 / 12) * (index + 1)
|
||||||
|
width: 30
|
||||||
|
|
||||||
|
property alias field: fieldItem
|
||||||
|
Item {
|
||||||
|
id: fieldItem
|
||||||
|
anchors { left: parent.left; top: parent.top; right: parent.right }
|
||||||
|
height: width
|
||||||
|
|
||||||
|
Label {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: index + 1
|
||||||
|
rotation: -delegate.rotation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: hours24
|
||||||
|
|
||||||
|
property int selectedIndex: root.hour - 12
|
||||||
|
|
||||||
|
model: 12
|
||||||
|
delegate: Item {
|
||||||
|
id: delegate
|
||||||
|
visible: d.mode == "hours"
|
||||||
|
anchors.centerIn: parent
|
||||||
|
height: parent.height - 80
|
||||||
|
rotation: (360 / 12) * (index + 12)
|
||||||
|
width: 30
|
||||||
|
|
||||||
|
property alias field: fieldItem
|
||||||
|
Item {
|
||||||
|
id: fieldItem
|
||||||
|
anchors { left: parent.left; top: parent.top; right: parent.right }
|
||||||
|
height: width
|
||||||
|
|
||||||
|
Label {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: index + 12 == 12 ? "00" : index + 12
|
||||||
|
rotation: -delegate.rotation
|
||||||
|
opacity: .8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: minutes
|
||||||
|
|
||||||
|
property int selectedIndex: 0
|
||||||
|
readonly property int selectedMinute: selectedIndex
|
||||||
|
|
||||||
|
model: 60
|
||||||
|
delegate: Item {
|
||||||
|
id: delegate
|
||||||
|
visible: d.mode == "minutes"
|
||||||
|
anchors.centerIn: parent
|
||||||
|
height: parent.height
|
||||||
|
rotation: (360 / 60) * (index)
|
||||||
|
width: 30
|
||||||
|
|
||||||
|
property alias field: fieldItem
|
||||||
|
Item {
|
||||||
|
id: fieldItem
|
||||||
|
anchors { left: parent.left; top: parent.top; right: parent.right }
|
||||||
|
height: width
|
||||||
|
|
||||||
|
Label {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: index
|
||||||
|
rotation: -delegate.rotation
|
||||||
|
visible: index % 5 == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: newDot
|
||||||
|
height: (parent.height + 10) - (d.mode == "hours" && (root.hour == 0 || root.hour > 12) ? 80 : 0)
|
||||||
|
width: 40
|
||||||
|
anchors.centerIn: parent
|
||||||
|
z: -1
|
||||||
|
rotation: {
|
||||||
|
if (d.mode == "hours") {
|
||||||
|
if (root.hour > 0 && root.hour < 13) {
|
||||||
|
return root.hour * 360 / 12
|
||||||
|
}
|
||||||
|
return (root.hour - 12 % 12) * 360 / 12
|
||||||
|
}
|
||||||
|
return root.minute * 360 / 60
|
||||||
|
}
|
||||||
|
Behavior on height { NumberAnimation { duration: 100 } }
|
||||||
|
Behavior on rotation { RotationAnimation { duration: 100; direction: RotationAnimation.Shortest } }
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors { left: parent.left; top: parent.top; right: parent.right }
|
||||||
|
height: width
|
||||||
|
color: app.accentColor
|
||||||
|
radius: width / 2
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
width: 5
|
||||||
|
height: parent.height / 2
|
||||||
|
color: app.accentColor
|
||||||
|
radius: width / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
onPositionChanged: update();
|
||||||
|
onReleased: {
|
||||||
|
if (d.mode == "hours") {
|
||||||
|
selectMinutes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function update() {
|
||||||
|
var angle = calculateAngle(mouseX, mouseY);
|
||||||
|
|
||||||
|
var items = d.mode == "hours" ? 12 : 60
|
||||||
|
|
||||||
|
// angle : 360 = num : 12
|
||||||
|
var selected = Math.round(angle * items / 360) % items;
|
||||||
|
|
||||||
|
if (d.mode == "hours") {
|
||||||
|
if (calculateDistanceToCenter(mouseX, mouseY) < (width / 2) - 40) {
|
||||||
|
selected = selected + 12
|
||||||
|
}
|
||||||
|
// swap 12 and 00
|
||||||
|
if (selected === 12) {
|
||||||
|
selected = 0
|
||||||
|
} else if (selected === 0) {
|
||||||
|
selected = 12
|
||||||
|
}
|
||||||
|
if (root.hour !== selected) {
|
||||||
|
root.hour = selected
|
||||||
|
PlatformHelper.vibrate(PlatformHelper.HapticsFeedbackSelection)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (root.minute !== selected) {
|
||||||
|
root.minute = selected
|
||||||
|
PlatformHelper.vibrate(PlatformHelper.HapticsFeedbackSelection)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateAngle(mouseX, mouseY) {
|
||||||
|
// transform coords to center of dial
|
||||||
|
mouseX -= width / 2
|
||||||
|
mouseY -= height / 2
|
||||||
|
|
||||||
|
var rad = Math.atan(mouseY / mouseX);
|
||||||
|
var angle = rad * 180 / Math.PI
|
||||||
|
|
||||||
|
angle += 90;
|
||||||
|
|
||||||
|
if (mouseX < 0 && mouseY >= 0) angle = 180 + angle;
|
||||||
|
if (mouseX < 0 && mouseY < 0) angle = 180 + angle;
|
||||||
|
|
||||||
|
return angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateDistanceToCenter(mouseX, mouseY) {
|
||||||
|
var a = mouseY - (height / 2)
|
||||||
|
var b = mouseX - (width / 2)
|
||||||
|
var c = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2))
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -8,20 +8,18 @@ import "../components"
|
|||||||
Page {
|
Page {
|
||||||
id: root
|
id: root
|
||||||
header: NymeaHeader {
|
header: NymeaHeader {
|
||||||
text: qsTr("Box settings")
|
text: qsTr("General settings")
|
||||||
backButtonVisible: true
|
backButtonVisible: true
|
||||||
onBackPressed: pageStack.pop()
|
onBackPressed: pageStack.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: settingsColumn
|
id: settingsGrid
|
||||||
anchors { left: parent.left; right: parent.right; top: parent.top }
|
anchors { horizontalCenter: parent.horizontalCenter; top: parent.top; margins: app.margins }
|
||||||
|
width: Math.min(500, parent.width - app.margins * 2)
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: app.margins
|
|
||||||
Layout.leftMargin: app.margins
|
|
||||||
Layout.rightMargin: app.margins
|
|
||||||
spacing: app.margins
|
spacing: app.margins
|
||||||
Label {
|
Label {
|
||||||
text: qsTr("Name")
|
text: qsTr("Name")
|
||||||
@ -40,63 +38,119 @@ Page {
|
|||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: app.margins
|
visible: engine.jsonRpcClient.ensureServerVersion("4.1") && engine.systemController.automaticTimeAvailable
|
||||||
Layout.rightMargin: app.margins
|
|
||||||
spacing: app.margins
|
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
|
text: qsTr("Set date and time automatically")
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: qsTr("Language")
|
|
||||||
}
|
}
|
||||||
ComboBox {
|
CheckBox {
|
||||||
id: languageBox
|
checked: engine.systemController.automaticTime
|
||||||
Layout.fillWidth: true
|
onClicked: {
|
||||||
model: engine.nymeaConfiguration.availableLanguages
|
engine.systemController.automaticTime = checked
|
||||||
currentIndex: model.indexOf(engine.nymeaConfiguration.language)
|
|
||||||
contentItem: Label {
|
|
||||||
leftPadding: app.margins / 2
|
|
||||||
text: Qt.locale(languageBox.displayText).nativeLanguageName + " (" + Qt.locale(languageBox.displayText).nativeCountryName + ")"
|
|
||||||
elide: Text.ElideRight
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate: ItemDelegate {
|
|
||||||
width: languageBox.width
|
|
||||||
contentItem: Label {
|
|
||||||
text: Qt.locale(modelData).nativeLanguageName + " (" + Qt.locale(modelData).nativeCountryName + ")"
|
|
||||||
elide: Text.ElideRight
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
}
|
|
||||||
highlighted: languageBox.highlightedIndex === index
|
|
||||||
}
|
|
||||||
onActivated: {
|
|
||||||
engine.nymeaConfiguration.language = currentText;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: app.margins
|
|
||||||
Layout.rightMargin: app.margins
|
|
||||||
spacing: app.margins
|
spacing: app.margins
|
||||||
|
Layout.preferredHeight: dateButton.implicitHeight
|
||||||
|
visible: engine.jsonRpcClient.ensureServerVersion("4.1")
|
||||||
|
Label {
|
||||||
|
text: qsTr("Date")
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: engine.systemController.serverTime.toLocaleDateString()
|
||||||
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
id: dateButton
|
||||||
|
visible: !engine.systemController.automaticTime && engine.systemController.timeManagementAvailable
|
||||||
|
contentItem: Item {
|
||||||
|
ColorIcon {
|
||||||
|
name: "../images/edit.svg"
|
||||||
|
color: app.foregroundColor
|
||||||
|
anchors.centerIn: parent
|
||||||
|
height: parent.height
|
||||||
|
width: height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
var popup = datePickerComponent.createObject(root, {dateTime: engine.systemController.serverTime})
|
||||||
|
popup.accepted.connect(function() {
|
||||||
|
print("setting new date", popup.dateTime)
|
||||||
|
engine.systemController.serverTime = popup.dateTime
|
||||||
|
})
|
||||||
|
popup.open();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: app.margins
|
||||||
|
Layout.preferredHeight: timeButton.implicitHeight
|
||||||
|
visible: engine.jsonRpcClient.ensureServerVersion("4.1")
|
||||||
|
Label {
|
||||||
|
text: qsTr("Time")
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: engine.systemController.serverTime.toLocaleTimeString(/*Locale.ShortTimeString*/)
|
||||||
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
id: timeButton
|
||||||
|
visible: !engine.systemController.automaticTime && engine.systemController.timeManagementAvailable
|
||||||
|
contentItem: Item {
|
||||||
|
ColorIcon {
|
||||||
|
name: "../images/edit.svg"
|
||||||
|
color: app.foregroundColor
|
||||||
|
anchors.centerIn: parent
|
||||||
|
height: parent.height
|
||||||
|
width: height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
var popup = timePickerComponent.createObject(root, {hour: engine.systemController.serverTime.getHours(), minute: engine.systemController.serverTime.getMinutes()})
|
||||||
|
popup.accepted.connect(function() {
|
||||||
|
var date = new Date(engine.systemController.serverTime)
|
||||||
|
date.setHours(popup.hour);
|
||||||
|
date.setMinutes(popup.minute)
|
||||||
|
engine.systemController.serverTime = date;
|
||||||
|
})
|
||||||
|
popup.open();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: app.margins
|
||||||
|
visible: engine.jsonRpcClient.ensureServerVersion("4.1")
|
||||||
Label {
|
Label {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: qsTr("Time zone")
|
text: qsTr("Time zone")
|
||||||
}
|
}
|
||||||
ComboBox {
|
ComboBox {
|
||||||
Layout.minimumWidth: 200
|
Layout.minimumWidth: 200
|
||||||
model: engine.nymeaConfiguration.timezones
|
model: engine.systemController.timeZones
|
||||||
currentIndex: model.indexOf(engine.nymeaConfiguration.timezone)
|
currentIndex: model.indexOf(engine.systemController.serverTimeZone)
|
||||||
onActivated: {
|
onActivated: {
|
||||||
engine.nymeaConfiguration.timezone = currentText;
|
engine.systemController.serverTimeZone = currentText;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.margins: app.margins
|
|
||||||
text: qsTr("Reboot %1:core").arg(app.systemName)
|
text: qsTr("Reboot %1:core").arg(app.systemName)
|
||||||
visible: engine.systemController.powerManagementAvailable
|
visible: engine.systemController.powerManagementAvailable
|
||||||
onClicked: {
|
onClicked: {
|
||||||
@ -117,7 +171,6 @@ Page {
|
|||||||
}
|
}
|
||||||
Button {
|
Button {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.margins: app.margins
|
|
||||||
text: qsTr("Shutdown %1:core").arg(app.systemName)
|
text: qsTr("Shutdown %1:core").arg(app.systemName)
|
||||||
visible: engine.systemController.powerManagementAvailable
|
visible: engine.systemController.powerManagementAvailable
|
||||||
onClicked: {
|
onClicked: {
|
||||||
@ -137,4 +190,48 @@ Page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: timePickerComponent
|
||||||
|
Dialog {
|
||||||
|
id: timePicker
|
||||||
|
property int maxSize: Math.min(parent.width, parent.height)
|
||||||
|
property int size: Math.min(maxSize, 500)
|
||||||
|
property alias hour: p.hour
|
||||||
|
property alias minute: p.minute
|
||||||
|
width: size - 80
|
||||||
|
height: size
|
||||||
|
x: (parent.width - width) / 2
|
||||||
|
y: (parent.height - height) / 2
|
||||||
|
|
||||||
|
TimePicker {
|
||||||
|
id: p
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
}
|
||||||
|
standardButtons: Dialog.Ok | Dialog.Cancel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: datePickerComponent
|
||||||
|
Dialog {
|
||||||
|
id: datePicker
|
||||||
|
property int maxSize: Math.min(parent.width, parent.height)
|
||||||
|
property int size: Math.min(maxSize, 500)
|
||||||
|
property alias dateTime: p.date
|
||||||
|
width: size - 80
|
||||||
|
height: size
|
||||||
|
x: (parent.width - width) / 2
|
||||||
|
y: (parent.height - height) / 2
|
||||||
|
|
||||||
|
DatePicker {
|
||||||
|
id: p
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
date: datePicker.dateTime
|
||||||
|
}
|
||||||
|
standardButtons: Dialog.Ok | Dialog.Cancel
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user