diff --git a/libnymea-app/system/systemcontroller.cpp b/libnymea-app/system/systemcontroller.cpp index 96cd9e85..3a838509 100644 --- a/libnymea-app/system/systemcontroller.cpp +++ b/libnymea-app/system/systemcontroller.cpp @@ -25,20 +25,23 @@ #include "systemcontroller.h" #include "types/package.h" -#include "types/repository.h" #include "types/packages.h" #include "types/repositories.h" +#include "types/repository.h" -#include #include +#include +#include + #include "logging.h" NYMEA_LOGGING_CATEGORY(dcSystemController, "SystemController") -SystemController::SystemController(JsonRpcClient *jsonRpcClient, QObject *parent): - QObject(parent), - m_jsonRpcClient(jsonRpcClient) +SystemController::SystemController(JsonRpcClient *jsonRpcClient, QObject *parent) + : QObject(parent) + , m_jsonRpcClient(jsonRpcClient) { m_jsonRpcClient->registerNotificationHandler(this, "System", "notificationReceived"); + m_packages = new Packages(this); m_repositories = new Repositories(this); @@ -73,6 +76,11 @@ bool SystemController::updateManagementAvailable() const return m_updateManagementAvailable; } +SystemController::UpdateType SystemController::updateManagementType() const +{ + return m_updateManagementType; +} + int SystemController::restart() { return m_jsonRpcClient->sendCommand("System.Restart", this, "restartResponse"); @@ -98,6 +106,11 @@ bool SystemController::updateRunning() const return m_updateRunning; } +int SystemController::updateProgress() const +{ + return m_updateProgress; +} + void SystemController::checkForUpdates() { m_jsonRpcClient->sendCommand("System.CheckForUpdates"); @@ -172,7 +185,7 @@ QString SystemController::serverTimeZone() const // NOTE: Ideally we'd just set the TimeZone of our serverTime prooperly, however, there's a bug on Android // Which doesn't allow to create QTimeZone objects by IANA id.... So, let's keep that separated in a string // https://bugreports.qt.io/browse/QTBUG-83438 -// return m_serverTime.timeZone().id(); + // return m_serverTime.timeZone().id(); return m_serverTimeZone; } @@ -207,12 +220,26 @@ QString SystemController::deviceSerialNumber() const void SystemController::getCapabilitiesResponse(int /*commandId*/, const QVariantMap &data) { + qCDebug(dcSystemController()) << data; m_powerManagementAvailable = data.value("powerManagement").toBool(); emit powerManagementAvailableChanged(); m_updateManagementAvailable = data.value("updateManagement").toBool(); emit updateManagementAvailableChanged(); + // Since API version 8.5 + if (data.contains("updateManagementType")) { + QMetaEnum updateTypeEnum = QMetaEnum::fromType(); + m_updateManagementType = static_cast(updateTypeEnum.keyToValue(data.value("updateManagementType").toByteArray())); + } else { + // Property exists since API 8.5, if there is an update management available, default to UpdateTypePackageManager + if (m_updateManagementAvailable) { + m_updateManagementType = UpdateTypePackageManager; + } else { + m_updateManagementType = UpdateTypeNone; + } + } + m_timeManagementAvailable = data.value("timeManagement").toBool(); emit timeManagementAvailableChanged(); @@ -226,7 +253,15 @@ void SystemController::getCapabilitiesResponse(int /*commandId*/, const QVariant m_jsonRpcClient->sendCommand("System.GetTime", this, "getServerTimeResponse"); } - qCDebug(dcSystemController) << "nymea:core capabilities: Power management:" << m_powerManagementAvailable << "Update management:" << m_updateManagementAvailable << "Time management:" << m_timeManagementAvailable; + qCDebug(dcSystemController()) + << "nymea:core capabilities: Power management:" + << m_powerManagementAvailable + << "Update management:" + << m_updateManagementAvailable + << "Update management type:" + << m_updateManagementType + << "Time management:" + << m_timeManagementAvailable; } void SystemController::getUpdateStatusResponse(int /*commandId*/, const QVariantMap &data) @@ -234,13 +269,17 @@ void SystemController::getUpdateStatusResponse(int /*commandId*/, const QVariant qCDebug(dcSystemController()) << "Update status:" << qUtf8Printable(QJsonDocument::fromVariant(data).toJson(QJsonDocument::Indented)); m_updateManagementBusy = data.value("busy").toBool(); m_updateRunning = data.value("updateRunning").toBool(); + m_updateProgress = data.value("updateProgress", -1).toInt(); // Since API 8.5, optional + emit updateRunningChanged(); + emit updateManagementBusyChanged(); + emit updateProgressChanged(); } void SystemController::getPackagesResponse(int commandId, const QVariantMap &data) { Q_UNUSED(commandId) - qCDebug(dcSystemController) << "Packages:" << qUtf8Printable(QJsonDocument::fromVariant(data).toJson(QJsonDocument::Indented)); + qCDebug(dcSystemController()) << "Packages:" << qUtf8Printable(QJsonDocument::fromVariant(data).toJson(QJsonDocument::Indented)); foreach (const QVariant &packageVariant, data.value("packages").toList()) { QString id = packageVariant.toMap().value("id").toString(); QString displayName = packageVariant.toMap().value("displayName").toString(); @@ -269,12 +308,12 @@ void SystemController::getRepositoriesResponse(int /*commandId*/, const QVariant void SystemController::removePackageResponse(int commandId, const QVariantMap ¶ms) { - qCDebug(dcSystemController) << "Remove result" << commandId << params; + qCDebug(dcSystemController()) << "Remove result" << commandId << params; } void SystemController::enableRepositoryResponse(int commandId, const QVariantMap ¶ms) { - qCDebug(dcSystemController) << "Enable repo response" << params; + qCDebug(dcSystemController()) << "Enable repo response" << params; emit enableRepositoryFinished(commandId, params.value("success").toBool()); } @@ -286,7 +325,7 @@ void SystemController::getServerTimeResponse(int commandId, const QVariantMap &p // Which doesn't allow to create QTimeZone objects by IANA id.... So, let's keep that separated in a string // https://bugreports.qt.io/browse/QTBUG-83438 -// m_serverTime.setTimeZone(QTimeZone(params.value("timeZone").toString().toUtf8())); + // m_serverTime.setTimeZone(QTimeZone(params.value("timeZone").toString().toUtf8())); m_serverTimeZone = params.value("timeZone").toString(); emit serverTimeZoneChanged(); @@ -302,12 +341,12 @@ void SystemController::getServerTimeResponse(int commandId, const QVariantMap &p emit automaticTimeAvailableChanged(); m_automaticTime = params.value("automaticTime").toBool(); emit automaticTimeChanged(); - qCDebug(dcSystemController) << "Server time:" << m_serverTime << "Automatic Time available:" << m_automaticTimeAvailable << "Automatic time:" << m_automaticTime; + qCDebug(dcSystemController()) << "Server time:" << m_serverTime << "Automatic Time available:" << m_automaticTimeAvailable << "Automatic time:" << m_automaticTime; } void SystemController::setTimeResponse(int commandId, const QVariantMap ¶ms) { - qCDebug(dcSystemController) << "set time response" << commandId << params; + qCDebug(dcSystemController()) << "set time response" << commandId << params; } void SystemController::restartResponse(int commandId, const QVariantMap ¶ms) @@ -338,18 +377,26 @@ void SystemController::getSystemInfoResponse(int commandId, const QVariantMap &p void SystemController::notificationReceived(const QVariantMap &data) { QString notification = data.value("notification").toString(); + const QVariantMap paramsMap = data.value("params").toMap(); if (notification == "System.UpdateStatusChanged") { - qCDebug(dcSystemController) << "System.UpdateStatusChanged:" << data.value("params").toMap(); - if (m_updateManagementBusy != data.value("params").toMap().value("busy").toBool()) { - m_updateManagementBusy = data.value("params").toMap().value("busy").toBool(); + qCDebug(dcSystemController()) << "System.UpdateStatusChanged:" << paramsMap; + if (m_updateManagementBusy != paramsMap.value("busy").toBool()) { + m_updateManagementBusy = paramsMap.value("busy").toBool(); emit updateManagementBusyChanged(); } - if (m_updateRunning != data.value("params").toMap().value("updateRunning").toBool()) { - m_updateRunning = data.value("params").toMap().value("updateRunning").toBool(); + if (m_updateRunning != paramsMap.value("updateRunning").toBool()) { + m_updateRunning = paramsMap.value("updateRunning").toBool(); emit updateRunningChanged(); } + + // Since API 8.5, optional, not supported or not running = -1 + if (m_updateProgress != paramsMap.value("updateProgress", -1).toInt()) { + m_updateProgress = paramsMap.value("updateProgress").toInt(); + emit updateProgressChanged(); + } + } else if (notification == "System.PackageAdded") { - QVariantMap packageMap = data.value("params").toMap().value("package").toMap(); + QVariantMap packageMap = paramsMap.value("package").toMap(); QString id = packageMap.value("id").toString(); QString displayName = packageMap.value("displayName").toString(); Package *p = new Package(id, displayName); @@ -362,7 +409,7 @@ void SystemController::notificationReceived(const QVariantMap &data) p->setCanRemove(packageMap.value("canRemove").toBool()); m_packages->addPackage(p); } else if (notification == "System.PackageChanged") { - QVariantMap packageMap = data.value("params").toMap().value("package").toMap(); + QVariantMap packageMap = paramsMap.value("package").toMap(); QString id = packageMap.value("id").toString(); Package *p = m_packages->getPackage(id); if (!p) { @@ -377,17 +424,17 @@ void SystemController::notificationReceived(const QVariantMap &data) p->setRollbackAvailable(packageMap.value("rollbackAvailable").toBool()); p->setCanRemove(packageMap.value("canRemove").toBool()); } else if (notification == "System.PackageRemoved") { - QString packageId = data.value("params").toMap().value("packageId").toString(); + QString packageId = paramsMap.value("packageId").toString(); m_packages->removePackage(packageId); } else if (notification == "System.RepositoryAdded") { - QVariantMap repoMap = data.value("params").toMap().value("repository").toMap(); + QVariantMap repoMap = paramsMap.value("repository").toMap(); QString id = repoMap.value("id").toString(); QString displayName = repoMap.value("displayName").toString(); Repository *repo = new Repository(id, displayName); repo->setEnabled(repoMap.value("enabled").toBool()); m_repositories->addRepository(repo); } else if (notification == "System.RepositoryChanged") { - QVariantMap repoMap = data.value("params").toMap().value("repository").toMap(); + QVariantMap repoMap = paramsMap.value("repository").toMap(); QString id = repoMap.value("id").toString(); Repository *repo = m_repositories->getRepository(id); if (!repo) { @@ -396,16 +443,36 @@ void SystemController::notificationReceived(const QVariantMap &data) } repo->setEnabled(repoMap.value("enabled").toBool()); } else if (notification == "System.RepositoryRemoved") { - QString repositoryId = data.value("params").toMap().value("repositoryId").toString(); + QString repositoryId = paramsMap.value("repositoryId").toString(); m_repositories->removeRepository(repositoryId); } else if (notification == "System.CapabilitiesChanged") { - m_powerManagementAvailable = data.value("params").toMap().value("powerManagement").toBool(); - m_updateManagementAvailable = data.value("params").toMap().value("updateManagement").toBool(); - qWarning() << "System capabilites changed: power management:" << m_powerManagementAvailable << "update management:" << m_updateManagementAvailable; + m_powerManagementAvailable = paramsMap.value("powerManagement").toBool(); + m_updateManagementAvailable = paramsMap.value("updateManagement").toBool(); + if (paramsMap.contains("updateManagementType")) { + QMetaEnum updateTypeEnum = QMetaEnum::fromType(); + m_updateManagementType = static_cast(updateTypeEnum.keyToValue(paramsMap.value("updateManagementType").toByteArray())); + } else { + // Property exists since API 8.5, if there is an update management available, default to UpdateTypePackageManager + if (m_updateManagementAvailable) { + m_updateManagementType = UpdateTypePackageManager; + } else { + m_updateManagementType = UpdateTypeNone; + } + } + + qCDebug(dcSystemController()) + << "System capabilites changed: power management:" + << m_powerManagementAvailable + << "update management:" + << m_updateManagementAvailable + << "update management type:" + << m_updateManagementType; emit powerManagementAvailableChanged(); emit updateManagementAvailableChanged(); + emit updateManagementTypeChanged(); + } else if (notification == "System.TimeConfigurationChanged") { - qCDebug(dcSystemController) << "System time configuration changed" << data.value("params").toMap().value("timeZone").toByteArray(); + qCDebug(dcSystemController()) << "System time configuration changed" << data.value("params").toMap().value("timeZone").toByteArray(); // NOTE: Ideally we'd just set the TimeZone of our serverTime prooperly, however, there's a bug on Android // Which doesn't allow to create QTimeZone objects by IANA id.... So, let's keep that separated in a string diff --git a/libnymea-app/system/systemcontroller.h b/libnymea-app/system/systemcontroller.h index 84a441a8..5003ce35 100644 --- a/libnymea-app/system/systemcontroller.h +++ b/libnymea-app/system/systemcontroller.h @@ -35,14 +35,18 @@ class SystemController : public QObject { Q_OBJECT Q_PROPERTY(bool powerManagementAvailable READ powerManagementAvailable NOTIFY powerManagementAvailableChanged) + // Whether the update mechanism is available in the connected core Q_PROPERTY(bool updateManagementAvailable READ updateManagementAvailable NOTIFY updateManagementAvailableChanged) + Q_PROPERTY(UpdateType updateManagementType READ updateManagementType NOTIFY updateManagementTypeChanged FINAL) Q_PROPERTY(bool timeManagementAvailable READ timeManagementAvailable NOTIFY timeManagementAvailableChanged) Q_PROPERTY(bool updateManagementBusy READ updateManagementBusy NOTIFY updateManagementBusyChanged) Q_PROPERTY(bool updateRunning READ updateRunning NOTIFY updateRunningChanged) - Q_PROPERTY(Packages* packages READ packages CONSTANT) - Q_PROPERTY(Repositories* repositories READ repositories CONSTANT) + Q_PROPERTY(int updateProgress READ updateProgress NOTIFY updateProgressChanged) + + Q_PROPERTY(Packages *packages READ packages 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) @@ -53,23 +57,34 @@ class SystemController : public QObject Q_PROPERTY(QString deviceSerialNumber READ deviceSerialNumber NOTIFY deviceSerialNumberChanged) public: + enum UpdateType { + UpdateTypeNone, + UpdateTypeSystem, + UpdateTypePackageManager + }; + Q_ENUM(UpdateType) + explicit SystemController(JsonRpcClient *jsonRpcClient, QObject *parent = nullptr); void init(); bool powerManagementAvailable() const; + Q_INVOKABLE int restart(); Q_INVOKABLE int reboot(); Q_INVOKABLE int shutdown(); bool updateManagementAvailable() const; + UpdateType updateManagementType() const; + bool updateManagementBusy() const; bool updateRunning() const; + int updateProgress() const; Q_INVOKABLE void checkForUpdates(); - Packages* packages() const; + Packages *packages() const; Q_INVOKABLE void updatePackages(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); bool timeManagementAvailable() const; @@ -87,9 +102,11 @@ public: signals: void powerManagementAvailableChanged(); void updateManagementAvailableChanged(); + void updateManagementTypeChanged(); void timeManagementAvailableChanged(); void updateManagementBusyChanged(); void updateRunningChanged(); + void updateProgressChanged(); void enableRepositoryFinished(int id, bool success); void serverTimeChanged(); void serverTimeZoneChanged(); @@ -117,7 +134,6 @@ private slots: void notificationReceived(const QVariantMap &data); - protected: void timerEvent(QTimerEvent *event) override; @@ -126,10 +142,12 @@ private: bool m_powerManagementAvailable = false; bool m_updateManagementAvailable = false; + UpdateType m_updateManagementType = UpdateTypeNone; bool m_timeManagementAvailable = false; bool m_updateManagementBusy = false; bool m_updateRunning = false; + int m_updateProgress = -1; Packages *m_packages = nullptr; Repositories *m_repositories = nullptr; diff --git a/nymea-app/ui/appsettings/LookAndFeelSettingsPage.qml b/nymea-app/ui/appsettings/LookAndFeelSettingsPage.qml index 95657a19..07688e9d 100644 --- a/nymea-app/ui/appsettings/LookAndFeelSettingsPage.qml +++ b/nymea-app/ui/appsettings/LookAndFeelSettingsPage.qml @@ -69,12 +69,16 @@ SettingsPageBase { Layout.fillWidth: true Layout.leftMargin: app.margins Layout.rightMargin: app.margins + visible: !kioskMode && Qt.platform.os !== "ios" + Label { Layout.fillWidth: true text: qsTr("View mode") } + ComboBox { + Layout.minimumWidth: 200 model: [qsTr("Windowed"), qsTr("Maximized"), qsTr("Fullscreen"), qsTr("Automatic")] currentIndex: { switch (settings.viewMode) { diff --git a/nymea-app/ui/components/UpdateRunningOverlay.qml b/nymea-app/ui/components/UpdateRunningOverlay.qml index 636fc458..d0c945a3 100644 --- a/nymea-app/ui/components/UpdateRunningOverlay.qml +++ b/nymea-app/ui/components/UpdateRunningOverlay.qml @@ -64,6 +64,15 @@ Rectangle { wrapMode: Text.WordWrap font.pixelSize: app.largeFont } + + ProgressBar { + Layout.fillWidth: true + Layout.leftMargin: app.margins + Layout.rightMargin: app.margins + visible: engine.systemController.updateProgress >= 0 + value: engine.systemController.updateProgress / 100.0 + } + Label { Layout.fillWidth: true Layout.margins: app.margins * 2 diff --git a/nymea-app/ui/system/SystemUpdatePage.qml b/nymea-app/ui/system/SystemUpdatePage.qml index 3f11bb72..ea6be6d2 100644 --- a/nymea-app/ui/system/SystemUpdatePage.qml +++ b/nymea-app/ui/system/SystemUpdatePage.qml @@ -26,6 +26,7 @@ import QtQuick import QtQuick.Controls import QtQuick.Controls.Material import QtQuick.Layouts + import Nymea import "../components" @@ -48,12 +49,12 @@ Page { Connections { target: engine.systemController - onEnableRepositoryFinished: { - if (!success) { - var popup = errorDialogComponent.createObject(app, {errorCode: qsTr("Failure adding repository.") }) - popup.open(); - } - } + onEnableRepositoryFinished: (id, success) => { + if (!success) { + var popup = errorDialogComponent.createObject(app, {errorCode: qsTr("Failure adding repository.") }) + popup.open(); + } + } } PackagesFilterModel { @@ -62,151 +63,350 @@ Page { updatesOnly: true } - ColumnLayout { - id: contentColumn + Loader { + id: updateTypeLoader anchors.fill: parent + sourceComponent: engine.systemController.updateManagementType === SystemController.UpdateTypeSystem ? + updateSystemComponent : + updatePackageManagerComponent - Item { - Layout.fillHeight: true - Layout.fillWidth: true - visible: updatesModel.count === 0 + } + + Component { + id: updateSystemComponent + + ColumnLayout { + id: systemUpdateContentColumn + + property Package systemPackage: engine.systemController.packages.get(0) + property bool changelogAvailable: systemUpdateContentColumn.systemPackage.changelog.length !== 0 + + anchors.fill: parent + anchors.margins: app.margins + + Item { + Layout.fillHeight: true + Layout.fillWidth: true + visible: updatesModel.count === 0 + + ColumnLayout { + width: parent.width + anchors.centerIn: parent + spacing: app.margins * 2 + + ColorIcon { + Layout.preferredHeight: Style.iconSize * 4 + Layout.preferredWidth: height + Layout.alignment: Qt.AlignHCenter + name: "qrc:/icons/system-update.svg" + color: Style.accentColor + RotationAnimation on rotation { + from: 0; to: 360 + duration: 2000 + running: engine.systemController.updateManagementBusy + loops: Animation.Infinite + } + } + + Label { + Layout.fillWidth: true + Layout.leftMargin: Style.margins + Layout.rightMargin: Style.margins + + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + text: engine.systemController.updateManagementBusy ? qsTr("Checking for updates...") : qsTr("Your system is up to date.") + } + + Label { + id: versionLabel + Layout.alignment: Qt.AlignHCenter + wrapMode: Text.WordWrap + text: qsTr("Version:") + " " + systemUpdateContentColumn.systemPackage.installedVersion + + MouseArea { + anchors.fill: parent + onClicked: { + PlatformHelper.toClipBoard(versionLabel.text); + ToolTip.show(qsTr("Version copied to clipboard"), 500); + } + } + } + + Button { + Layout.fillWidth: true + Layout.leftMargin: Style.margins + Layout.rightMargin: Style.margins + + text: qsTr("Check for updates") + enabled: !engine.systemController.updateManagementBusy + onClicked: { + engine.systemController.checkForUpdates() + } + } + } + } ColumnLayout { - width: parent.width - anchors.centerIn: parent - spacing: app.margins * 2 + Layout.fillHeight: true + Layout.fillWidth: true + visible: updatesModel.count > 0 - ColorIcon { - Layout.preferredHeight: Style.iconSize * 4 - Layout.preferredWidth: height - Layout.alignment: Qt.AlignHCenter - name: "qrc:/icons/system-update.svg" - color: Style.accentColor - RotationAnimation on rotation { - from: 0; to: 360 - duration: 2000 - running: engine.systemController.updateManagementBusy - loops: Animation.Infinite + RowLayout { + Layout.margins: app.margins + spacing: app.margins + + ColorIcon { + Layout.preferredHeight: Style.iconSize * 2 + Layout.preferredWidth: height + name: "qrc:/icons/system-update.svg" + color: Style.accentColor + RotationAnimation on rotation { + from: 0; to: 360 + duration: 2000 + running: engine.systemController.updateManagementBusy + loops: Animation.Infinite + } } + + Label { + Layout.fillWidth: true + text: engine.systemController.updateManagementBusy ? qsTr("Checking for updates...") : qsTr("%1 update available").arg(Configuration.systemName) + } + } + + + Button { + Layout.fillWidth: true + text: qsTr("Check again") + enabled: !engine.systemController.updateManagementBusy + onClicked: engine.systemController.checkForUpdates() + } + + NymeaSwipeDelegate { + Layout.fillWidth: true + text: qsTr("Installed version:") + subText: systemUpdateContentColumn.systemPackage.installedVersion + progressive: false + } + + NymeaSwipeDelegate { + Layout.fillWidth: true + text: qsTr("Candidate version:") + subText: systemUpdateContentColumn.systemPackage.candidateVersion + visible: systemUpdateContentColumn.systemPackage.updateAvailable || systemUpdateContentColumn.systemPackage.installedVersion.length === 0 + progressive: false + } + + ThinDivider { + visible: changelogAvailable } Label { Layout.fillWidth: true - Layout.margins: app.margins - horizontalAlignment: Text.AlignHCenter + Layout.leftMargin: Style.margins + Layout.rightMargin: Style.margins + + visible: changelogAvailable + text: qsTr("Update changelog:") + } + + Label { + Layout.fillWidth: true + Layout.leftMargin: Style.margins + Layout.rightMargin: Style.margins + + Layout.alignment: Qt.AlignHCenter wrapMode: Text.WordWrap - text: engine.systemController.updateManagementBusy ? qsTr("Checking for updates...") : qsTr("Your system is up to date.") + visible: changelogAvailable + text: systemPackage.changelog + + } + + Item { + Layout.fillWidth: true + Layout.fillHeight: true } Button { - Layout.alignment: Qt.AlignHCenter - text: qsTr("Check for updates") + Layout.fillWidth: true + //Layout.leftMargin: Style.margins + //Layout.rightMargin: Style.margins + + text: qsTr("Update") + visible: updatesModel.count > 0 enabled: !engine.systemController.updateManagementBusy onClicked: { - engine.systemController.checkForUpdates() + var dialog = Qt.createComponent(Qt.resolvedUrl("../components/NymeaDialog.qml")); + var text = qsTr("This will start a system update. Note that the update might take several minutes and your %1 system might not be functioning properly during this time and restart during the process.\nDo you want to proceed?").arg(Configuration.systemName) + var popup = dialog.createObject(app, + { + headerIcon: "qrc:/icons/system-update.svg", + title: qsTr("System update"), + text: text, + standardButtons: Dialog.Ok | Dialog.Cancel + }); + popup.open(); + popup.accepted.connect(function() { + engine.systemController.updatePackages() + }) } } } } + } + + + Component { + id: updatePackageManagerComponent ColumnLayout { - Layout.fillHeight: true - Layout.fillWidth: true - visible: updatesModel.count > 0 + id: contentColumn + anchors.fill: parent - RowLayout { - Layout.margins: app.margins - spacing: app.margins + Item { + Layout.fillHeight: true + Layout.fillWidth: true + Layout.leftMargin: Style.margins + Layout.rightMargin: Style.margins - ColorIcon { - Layout.preferredHeight: Style.iconSize * 2 - Layout.preferredWidth: height - name: "qrc:/icons/system-update.svg" - color: Style.accentColor - RotationAnimation on rotation { - from: 0; to: 360 - duration: 2000 - running: engine.systemController.updateManagementBusy - loops: Animation.Infinite - } - } + visible: updatesModel.count === 0 ColumnLayout { + width: parent.width + anchors.centerIn: parent + spacing: app.margins * 2 + + ColorIcon { + Layout.preferredHeight: Style.iconSize * 4 + Layout.preferredWidth: height + Layout.alignment: Qt.AlignHCenter + name: "qrc:/icons/system-update.svg" + color: Style.accentColor + RotationAnimation on rotation { + from: 0; to: 360 + duration: 2000 + running: engine.systemController.updateManagementBusy + loops: Animation.Infinite + } + } + Label { Layout.fillWidth: true - text: engine.systemController.updateManagementBusy ? qsTr("Checking for updates...") : qsTr("%n update(s) available", "", updatesModel.count) + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.WordWrap + text: engine.systemController.updateManagementBusy ? qsTr("Checking for updates...") : qsTr("Your system is up to date.") } - GridLayout { - columns: width > 250 ? 2 : 1 - Button { + + Button { + Layout.fillWidth: true + text: qsTr("Check for updates") + enabled: !engine.systemController.updateManagementBusy + onClicked: engine.systemController.checkForUpdates() + } + } + } + + ColumnLayout { + Layout.fillHeight: true + Layout.fillWidth: true + visible: updatesModel.count > 0 + + RowLayout { + spacing: Style.margins + Layout.leftMargin: Style.margins + Layout.rightMargin: Style.margins + + ColorIcon { + Layout.preferredHeight: Style.iconSize * 2 + Layout.preferredWidth: height + name: "qrc:/icons/system-update.svg" + color: Style.accentColor + RotationAnimation on rotation { + from: 0; to: 360 + duration: 2000 + running: engine.systemController.updateManagementBusy + loops: Animation.Infinite + } + } + + ColumnLayout { + Label { Layout.fillWidth: true - text: qsTr("Check again") - enabled: !engine.systemController.updateManagementBusy - onClicked: { - engine.systemController.checkForUpdates() + text: engine.systemController.updateManagementBusy ? qsTr("Checking for updates...") : qsTr("%n update(s) available", "", updatesModel.count) + } + GridLayout { + columns: width > 250 ? 2 : 1 + Button { + Layout.fillWidth: true + text: qsTr("Check again") + enabled: !engine.systemController.updateManagementBusy + onClicked: { + engine.systemController.checkForUpdates() + } + } + Button { + Layout.fillWidth: true + text: qsTr("Update all") + visible: updatesModel.count > 0 + enabled: !engine.systemController.updateManagementBusy + onClicked: { + var dialog = Qt.createComponent(Qt.resolvedUrl("../components/NymeaDialog.qml")); + var text = qsTr("This will start a system update. Note that the update might take several minutes and your %1 system might not be functioning properly during this time and restart during the process.\nDo you want to proceed?").arg(Configuration.systemName) + var popup = dialog.createObject(app, + { + headerIcon: "qrc:/icons/system-update.svg", + title: qsTr("System update"), + text: text, + standardButtons: Dialog.Ok | Dialog.Cancel + }); + popup.open(); + popup.accepted.connect(function() { + engine.systemController.updatePackages() + }) + } } } - Button { - Layout.fillWidth: true - text: qsTr("Update all") - visible: updatesModel.count > 0 - enabled: !engine.systemController.updateManagementBusy - onClicked: { - var dialog = Qt.createComponent(Qt.resolvedUrl("../components/NymeaDialog.qml")); - var text = qsTr("This will start a system update. Note that the update might take several minutes and your %1 system might not be functioning properly during this time and restart during the process.\nDo you want to proceed?").arg(Configuration.systemName) - var popup = dialog.createObject(app, - { - headerIcon: "qrc:/icons/system-update.svg", - title: qsTr("System update"), - text: text, - standardButtons: Dialog.Ok | Dialog.Cancel - }); - popup.open(); - popup.accepted.connect(function() { - engine.systemController.updatePackages() - }) - } + } + + } + + ThinDivider {} + + ListView { + Layout.fillWidth: true + Layout.fillHeight: true + visible: count > 0 + model: updatesModel + clip: true + delegate: NymeaSwipeDelegate { + width: parent.width + text: model.displayName + subText: model.candidateVersion + prominentSubText: false + iconName: model.updateAvailable + ? Qt.resolvedUrl("qrc:/icons/system-update.svg") + : Qt.resolvedUrl("qrc:/icons/view-" + (model.installedVersion.length > 0 ? "expand" : "collapse") + ".svg") + iconColor: model.updateAvailable + ? "green" + : model.installedVersion.length > 0 ? "blue" : Style.iconColor + onClicked: { + pageStack.push(Qt.resolvedUrl("PackageDetailsPage.qml"), {pkg: updatesModel.get(index)}) } } } - } ThinDivider {} - ListView { + NymeaSwipeDelegate { Layout.fillWidth: true - Layout.fillHeight: true - visible: count > 0 - model: updatesModel - clip: true - delegate: NymeaSwipeDelegate { - width: parent.width - text: model.displayName - subText: model.candidateVersion - prominentSubText: false - iconName: model.updateAvailable - ? Qt.resolvedUrl("qrc:/icons/system-update.svg") - : Qt.resolvedUrl("qrc:/icons/view-" + (model.installedVersion.length > 0 ? "expand" : "collapse") + ".svg") - iconColor: model.updateAvailable - ? "green" - : model.installedVersion.length > 0 ? "blue" : Style.iconColor - onClicked: { - pageStack.push(Qt.resolvedUrl("PackageDetailsPage.qml"), {pkg: updatesModel.get(index)}) - } + text: qsTr("Install or remove software") + onClicked: { + pageStack.push("PackageListPage.qml") } } } - - ThinDivider {} - - NymeaSwipeDelegate { - Layout.fillWidth: true - text: qsTr("Install or remove software") - onClicked: { - pageStack.push("PackageListPage.qml") - } - } } Component { @@ -253,8 +453,7 @@ Page { } } - UpdateRunningOverlay { - } + UpdateRunningOverlay { } Component { id: errorDialogComponent diff --git a/version.txt b/version.txt index bb070667..df46c1ce 100644 --- a/version.txt +++ b/version.txt @@ -1,2 +1,2 @@ -1.11.3 -700 +1.11.4 +701