Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabian Müller <fmueller@owncloud.com>2022-01-21 02:54:40 +0300
committerHannah von Reth <vonreth@kde.org>2022-03-14 16:23:05 +0300
commitd762e822ec35b99f9907c4a1e62d54f21020a4f0 (patch)
tree31009adf9813b131bcde778aba41b5f0f3b240af /src/gui/updater
parentd76f27f19ee91d4018dc2b407fb6516cc2d535f0 (diff)
Ask user whether to update or not
TODO: remember whether "skip update" button was pushed
Diffstat (limited to 'src/gui/updater')
-rw-r--r--src/gui/updater/CMakeLists.txt3
-rw-r--r--src/gui/updater/appimageupdateavailabledialog.cpp66
-rw-r--r--src/gui/updater/appimageupdateavailabledialog.h49
-rw-r--r--src/gui/updater/appimageupdateavailabledialog.ui185
-rw-r--r--src/gui/updater/appimageupdater.cpp52
5 files changed, 340 insertions, 15 deletions
diff --git a/src/gui/updater/CMakeLists.txt b/src/gui/updater/CMakeLists.txt
index 0f8021962..e0d36e984 100644
--- a/src/gui/updater/CMakeLists.txt
+++ b/src/gui/updater/CMakeLists.txt
@@ -33,6 +33,9 @@ if(WITH_APPIMAGEUPDATER)
message(STATUS "Including built-in libappimageupdate based updater")
set(appimageupdater_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/appimageupdateavailabledialog.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/appimageupdateavailabledialog.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/appimageupdateavailabledialog.ui
${CMAKE_CURRENT_SOURCE_DIR}/appimageupdater.cpp
${CMAKE_CURRENT_SOURCE_DIR}/appimageupdater.h
)
diff --git a/src/gui/updater/appimageupdateavailabledialog.cpp b/src/gui/updater/appimageupdateavailabledialog.cpp
new file mode 100644
index 000000000..13096e6ae
--- /dev/null
+++ b/src/gui/updater/appimageupdateavailabledialog.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 by Fabian Müller <fmueller@owncloud.com>
+ *
+ * This program 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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.
+ */
+
+#include "appimageupdateavailabledialog.h"
+#include <QStyle>
+
+#include "guiutility.h"
+#include "theme.h"
+#include "ui_appimageupdateavailabledialog.h"
+
+namespace OCC::Ui {
+
+AppImageUpdateAvailableDialog::AppImageUpdateAvailableDialog(const QVersionNumber &currentVersion, const QVersionNumber &newVersion, QWidget *parent)
+ : QDialog(parent)
+ , _ui(new ::Ui::AppImageUpdateAvailableDialogUi)
+{
+ _ui->setupUi(this);
+
+ setWindowIcon(style()->standardIcon(QStyle::SP_MessageBoxInformation));
+
+ // we want an immediate response from the user
+ setModal(true);
+
+ const auto *theme = Theme::instance();
+
+ // the strings in the .ui file are not marked for translation, they're just placeholders
+ _ui->installedVersionLabel->setText(tr("Installed version: %1").arg(currentVersion.toString()));
+ _ui->availableVersionLabel->setText(tr("Available update: %1").arg(newVersion.toString()));
+ _ui->infoLabel->setText(tr("An update is available for this AppImage of %1. Do you want to install this update?\n\nThe update will be performed in the background, and overwrite the current AppImage file. You need to restart the app to complete the update.").arg(theme->appNameGUI()));
+
+ _ui->appIconLabel->setPixmap(theme->aboutIcon().pixmap(QSize(128, 128)));
+
+ // we use custom icons to ensure a unified look on all platforms
+ _ui->buttonBox->button(QDialogButtonBox::Ok)->setIcon(Utility::getCoreIcon(QStringLiteral("check")));
+ _ui->buttonBox->button(QDialogButtonBox::Cancel)->setIcon(Utility::getCoreIcon(QStringLiteral("ban")));
+ _ui->skipButton->setIcon(Utility::getCoreIcon(QStringLiteral("step-forward")));
+
+ // the minimum size of the info label (and a few other labels) depends on their contents
+ // we can't persuade the dialog to resize automatically to the recommended size in Qt Designer, so we do it manually
+ resize(sizeHint());
+ // also, we want to prevent users from reducing the widget size too much, i.e., widgets would be hidden partially
+ setMinimumSize(sizeHint());
+
+ connect(_ui->skipButton, &QPushButton::clicked, this, [this]() {
+ emit skipUpdateButtonClicked();
+ reject();
+ });
+}
+
+AppImageUpdateAvailableDialog::~AppImageUpdateAvailableDialog()
+{
+ delete _ui;
+}
+
+}
diff --git a/src/gui/updater/appimageupdateavailabledialog.h b/src/gui/updater/appimageupdateavailabledialog.h
new file mode 100644
index 000000000..9b6313c0b
--- /dev/null
+++ b/src/gui/updater/appimageupdateavailabledialog.h
@@ -0,0 +1,49 @@
+/*
+* Copyright (C) 2022 by Fabian Müller <fmueller@owncloud.com>
+*
+* This program 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 2 of the License, or
+* (at your option) any later version.
+*
+* This program 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.
+ */
+
+#pragma once
+
+#include <QDialog>
+#include <QScopedPointer>
+#include <QVersionNumber>
+
+namespace Ui {
+class AppImageUpdateAvailableDialogUi;
+}
+
+namespace OCC::Ui {
+
+/**
+ * @brief Dialog shown when updates for the running AppImage are available
+ * @ingroup gui
+ */
+class AppImageUpdateAvailableDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit AppImageUpdateAvailableDialog(const QVersionNumber &currentVersion, const QVersionNumber &newVersion, QWidget *parent = nullptr);
+
+ ~AppImageUpdateAvailableDialog() override;
+
+signals:
+ /**
+ * Emitted when an update is explicitly skipped by the user.
+ */
+ void skipUpdateButtonClicked();
+
+private:
+ ::Ui::AppImageUpdateAvailableDialogUi *_ui;
+};
+
+}
diff --git a/src/gui/updater/appimageupdateavailabledialog.ui b/src/gui/updater/appimageupdateavailabledialog.ui
new file mode 100644
index 000000000..10b77efb3
--- /dev/null
+++ b/src/gui/updater/appimageupdateavailabledialog.ui
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AppImageUpdateAvailableDialogUi</class>
+ <widget class="QDialog" name="AppImageUpdateAvailableDialogUi">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>556</width>
+ <height>241</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string extracomment="AppImage update available dialog">Update available</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMinimumSize</enum>
+ </property>
+ <item>
+ <widget class="QLabel" name="appIconLabel">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="leftMargin">
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="installedVersionLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">Installed version:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="availableVersionLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">Available version:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="infoLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>350</width>
+ <height>10</height>
+ </size>
+ </property>
+ <property name="text">
+ <string notr="true">Info text placeholder</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="topMargin">
+ <number>10</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="skipButton">
+ <property name="text">
+ <string>Skip this version</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>AppImageUpdateAvailableDialogUi</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>AppImageUpdateAvailableDialogUi</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/gui/updater/appimageupdater.cpp b/src/gui/updater/appimageupdater.cpp
index d28b99a38..aaa1ec0f3 100644
--- a/src/gui/updater/appimageupdater.cpp
+++ b/src/gui/updater/appimageupdater.cpp
@@ -12,12 +12,18 @@
* for more details.
*/
+#include <QMessageBox>
#include <QTimer>
#include <appimage/update.h>
#include <chrono>
#include "appimageupdater.h"
#include "common/version.h"
+#include "theme.h"
+#include "settingsdialog.h"
+
+#include "appimageupdateavailabledialog.h"
+#include "application.h"
using namespace OCC;
using namespace std::chrono_literals;
@@ -123,38 +129,54 @@ bool AppImageUpdater::handleStartup()
void AppImageUpdater::versionInfoArrived(const UpdateInfo &info)
{
- if (info.version().isEmpty() || Version::versionWithBuildNumber() >= QVersionNumber::fromString(info.version())) {
+ const auto &currentVersion = Version::versionWithBuildNumber();
+ const auto newVersion = QVersionNumber::fromString(info.version());
+
+ if (info.version().isEmpty() || currentVersion >= newVersion) {
qCInfo(lcUpdater) << "Client is on latest version!";
setDownloadState(UpToDate);
return;
}
- const auto AppImageUpdaterShim = AppImageUpdaterShim::makeInstance(info.downloadUrl(), this);
+ const auto appImageUpdaterShim = AppImageUpdaterShim::makeInstance(info.downloadUrl(), this);
- if (AppImageUpdaterShim == nullptr) {
+ if (appImageUpdaterShim == nullptr) {
setDownloadState(DownloadFailed);
return;
}
- if (!AppImageUpdaterShim->isUpdateAvailable()) {
+ if (!appImageUpdaterShim->isUpdateAvailable()) {
qCCritical(lcUpdater) << "Update server reported that update is available, but AppImageUpdate disagrees, aborting";
setDownloadState(DownloadFailed);
return;
}
- // binding AppImageUpdaterShim shared pointer to finished callback makes sure the updater is cleaned up when it's done
- connect(AppImageUpdaterShim, &AppImageUpdaterShim::finished, this, [this](bool succeeded) {
- if (succeeded) {
- qCInfo(lcUpdater) << "AppImage update complete";
- setDownloadState(DownloadComplete);
- } else {
- qCInfo(lcUpdater) << "AppImage update failed";
- setDownloadState(DownloadFailed);
- }
+ auto dialog = new Ui::AppImageUpdateAvailableDialog(currentVersion, newVersion, ocApp()->gui()->settingsDialog());
+
+ connect(dialog, &Ui::AppImageUpdateAvailableDialog::skipUpdateButtonClicked, this, [this]() {
+ qCInfo(lcUpdater) << "Update skipped by user";
+
+ // TODO: remember this setting
+ });
+
+ connect(dialog, &QDialog::accepted, this, [this, appImageUpdaterShim]() {
+ // binding AppImageUpdaterShim shared pointer to finished callback makes sure the updater is cleaned up when it's done
+ connect(appImageUpdaterShim, &AppImageUpdaterShim::finished, this, [this](bool succeeded) {
+ if (succeeded) {
+ qCInfo(lcUpdater) << "AppImage update complete";
+ setDownloadState(DownloadComplete);
+ } else {
+ qCInfo(lcUpdater) << "AppImage update failed";
+ setDownloadState(DownloadFailed);
+ }
+ });
+
+ setDownloadState(Downloading);
+ appImageUpdaterShim->startUpdateInBackground();
});
- setDownloadState(Downloading);
- AppImageUpdaterShim->startUpdateInBackground();
+ dialog->show();
+ ownCloudGui::raiseDialog(dialog);
}
void AppImageUpdater::backgroundCheckForUpdate()