diff --git a/CMakeLists.txt b/CMakeLists.txt index 6246a9b..356910b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,9 @@ set(PROJECT_SOURCES src/releaseupgradewindow.h src/releaseupgradewindow.cpp src/releaseupgradewindow.ui + src/upgradedelaywindow.h + src/upgradedelaywindow.cpp + src/upgradedelaywindow.ui ${TS_FILES} ) diff --git a/src/lubuntu-update-backend b/src/lubuntu-update-backend index 62ffa93..6af78b7 100755 --- a/src/lubuntu-update-backend +++ b/src/lubuntu-update-backend @@ -165,4 +165,8 @@ elif [ "$1" = 'doupdate' ]; then fi echo 'Update installation complete.' +elif [ "$1" = 'doReleaseUpgrade' ]; then + do-release-upgrade -m desktop -f DistUpgradeViewKDE; +elif [ "$1" = 'declineReleaseUpgrade' ]; then + sed -i -E 's/^Prompt=(never|lts|normal)$/Prompt=never/' /etc/update-manager/release-upgrades; fi diff --git a/src/orchestrator.cpp b/src/orchestrator.cpp index 07353bf..135a8f2 100644 --- a/src/orchestrator.cpp +++ b/src/orchestrator.cpp @@ -1,11 +1,13 @@ #include "orchestrator.h" #include "mainwindow.h" #include "aptmanager.h" +#include "releaseupgradewindow.h" #include #include #include #include +#include #include #include @@ -40,11 +42,13 @@ Orchestrator::Orchestrator(QObject *parent) } } } + configFile.close(); connect(checkTimer, &QTimer::timeout, this, &Orchestrator::checkForUpdates); connect(trayIcon, &QSystemTrayIcon::activated, this, &Orchestrator::displayUpdater); connect(&updaterWindow, &MainWindow::updatesInstalled, this, &Orchestrator::handleUpdatesInstalled); connect(&updaterWindow, &MainWindow::updatesRefreshed, this, &Orchestrator::handleUpdatesRefreshed); + connect(&updaterWindow, &MainWindow::newReleaseAvailable, this, &Orchestrator::onNewReleaseAvailable); checkTimer->start(21600000); // check four times a day, at least one of those times unattended-upgrades should have refreshed the apt database @@ -131,9 +135,51 @@ void Orchestrator::onNewReleaseAvailable(QStringList releaseCodes) if (((releaseYear % 2 == 0) && (releaseMonth == 4)) || druType == "normal") { QDateTime now = QDateTime::currentDateTime(); if (nextUpgradeCheck < now) { - // TODO: attempt to show window here + ReleaseUpgradeWindow upgradeWindow(releaseCodes[i]); + upgradeWindow.exec(); + if (upgradeWindow.getUpgradeAccepted()) { + doReleaseUpgrade(); + } else if (upgradeWindow.getUpgradeDelayStamp() > 0) { + delayReleaseUpgrade(upgradeWindow.getUpgradeDelayStamp()); + } else { + declineReleaseUpgrade(); + } + break; } } } } } + +void Orchestrator::doReleaseUpgrade() +{ + QProcess druProcess; + druProcess.setProgram("/usr/bin/lxqt-sudo"); + druProcess.setArguments(QStringList() << "/usr/libexec/lubuntu-update-backend" << "doReleaseUpgrade"); + druProcess.start(); + druProcess.waitForFinished(-1); +} + +void Orchestrator::delayReleaseUpgrade(qint64 timestamp) +{ + QFile configFile(QDir::homePath() + "/.config/lubuntu-update.conf"); + bool success = configFile.open(QFile::WriteOnly); + if (success) { + configFile.write("nextDoReleaseUpgradeNotify="); + configFile.write(QString::number(timestamp).toUtf8()); + configFile.write("\n"); + } else { + qWarning() << "Could not write to " + QDir::homePath() + "/.config/lubuntu-update.conf, check permissions"; + } + configFile.close(); + nextUpgradeCheck = QDateTime::fromSecsSinceEpoch(timestamp); +} + +void Orchestrator::declineReleaseUpgrade() +{ + QProcess druProcess; + druProcess.setProgram("/usr/bin/lxqt-sudo"); + druProcess.setArguments(QStringList() << "/usr/libexec/lubuntu-update-backend" << "declineReleaseUpgrade"); + druProcess.start(); + druProcess.waitForFinished(-1); +} diff --git a/src/orchestrator.h b/src/orchestrator.h index 974c5ee..6083c42 100644 --- a/src/orchestrator.h +++ b/src/orchestrator.h @@ -9,6 +9,7 @@ class QTimer; class QSystemTrayIcon; +class ReleaseUpgradeWindow; class Orchestrator : public QObject { @@ -31,6 +32,9 @@ private: QList updateInfo; MainWindow updaterWindow; QDateTime nextUpgradeCheck; + void doReleaseUpgrade(); + void delayReleaseUpgrade(qint64 timestamp); + void declineReleaseUpgrade(); }; #endif // ORCHESTRATOR_H diff --git a/src/releaseupgradewindow.cpp b/src/releaseupgradewindow.cpp index 42acf6f..b425ea7 100644 --- a/src/releaseupgradewindow.cpp +++ b/src/releaseupgradewindow.cpp @@ -1,12 +1,18 @@ #include "releaseupgradewindow.h" #include "ui_releaseupgradewindow.h" +#include "upgradedelaywindow.h" + +#include +#include + ReleaseUpgradeWindow::ReleaseUpgradeWindow(QString releaseCode, QWidget *parent) : QDialog(parent), ui(new Ui::ReleaseUpgradeWindow) { ui->setupUi(this); ui->upgradeLabel->setText(tr("An upgrade to Lubuntu %1 is available! Would you like to install this upgrade now?").arg(releaseCode)); + code=releaseCode; connect(ui->upgradeButton, &QPushButton::clicked, this, &ReleaseUpgradeWindow::onUpgradeClicked); connect(ui->remindButton, &QPushButton::clicked, this, &ReleaseUpgradeWindow::onRemindClicked); connect(ui->declineButton, &QPushButton::clicked, this, &ReleaseUpgradeWindow::onDeclineClicked); @@ -17,17 +23,45 @@ ReleaseUpgradeWindow::~ReleaseUpgradeWindow() delete ui; } -void ReleaseUpgradeWindow::onUpgradeClicked() +bool ReleaseUpgradeWindow::getUpgradeAccepted() { + return upgradeAccepted; +} +qint64 ReleaseUpgradeWindow::getUpgradeDelayStamp() +{ + return upgradeDelayStamp; } -void ReleaseUpgradeWindow::onRemindClicked() +void ReleaseUpgradeWindow::onUpgradeClicked() { + upgradeAccepted = true; + this->done(0); +} +void ReleaseUpgradeWindow::onRemindClicked() +{ + UpgradeDelayWindow delayWindow; + delayWindow.exec(); + if (delayWindow.getDelayDays() > 0) { + QDateTime delayDateTime = QDateTime::currentDateTime(); + delayDateTime = delayDateTime.addDays(delayWindow.getDelayDays()); + upgradeAccepted = false; + upgradeDelayStamp = delayDateTime.toSecsSinceEpoch(); + this->done(0); + } } void ReleaseUpgradeWindow::onDeclineClicked() { - + QMessageBox confirmDialog; + confirmDialog.setWindowTitle(tr("Lubuntu Update")); + confirmDialog.setText(tr("You have declined the upgrade to Lubuntu %1.\nYou can upgrade manually by following the directions at https://manual.lubuntu.me/stable/D/upgrading.html.").arg(code)); + confirmDialog.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + int result = confirmDialog.exec(); + if (result == QMessageBox::Ok) { + upgradeDelayStamp = 0; + upgradeAccepted = false; + this->done(0); + } } diff --git a/src/releaseupgradewindow.h b/src/releaseupgradewindow.h index 2788665..0c68674 100644 --- a/src/releaseupgradewindow.h +++ b/src/releaseupgradewindow.h @@ -14,6 +14,8 @@ class ReleaseUpgradeWindow : public QDialog public: explicit ReleaseUpgradeWindow(QString releaseCode, QWidget *parent = nullptr); ~ReleaseUpgradeWindow(); + bool getUpgradeAccepted(); + qint64 getUpgradeDelayStamp(); private slots: void onUpgradeClicked(); @@ -22,6 +24,9 @@ private slots: private: Ui::ReleaseUpgradeWindow *ui; + QString code; + bool upgradeAccepted = false; + qint64 upgradeDelayStamp = 0; }; #endif // RELEASEUPGRADEWINDOW_H diff --git a/src/upgradedelaywindow.cpp b/src/upgradedelaywindow.cpp new file mode 100644 index 0000000..c86562e --- /dev/null +++ b/src/upgradedelaywindow.cpp @@ -0,0 +1,42 @@ +#include "upgradedelaywindow.h" +#include "ui_upgradedelaywindow.h" + +UpgradeDelayWindow::UpgradeDelayWindow(QWidget *parent) : + QDialog(parent), + ui(new Ui::UpgradeDelayWindow) +{ + ui->setupUi(this); + connect(ui->okButton, &QPushButton::clicked, this, &UpgradeDelayWindow::onOkClicked); + connect(ui->cancelButton, &QPushButton::clicked, this, &UpgradeDelayWindow::onCancelClicked); +} + +UpgradeDelayWindow::~UpgradeDelayWindow() +{ + delete ui; +} + +qint64 UpgradeDelayWindow::getDelayDays() +{ + return delayDays; +} + +void UpgradeDelayWindow::onOkClicked() +{ + switch (ui->timeTypeComboBox->currentIndex()) { + case 0: // days + delayDays = ui->timeSpinBox->value(); + break; + case 1: // weeks + delayDays = ui->timeSpinBox->value() * 7; + break; + case 2: // months + delayDays = ui->timeSpinBox->value() * 28; + break; + } + this->done(0); +} + +void UpgradeDelayWindow::onCancelClicked() +{ + this->done(0); +} diff --git a/src/upgradedelaywindow.h b/src/upgradedelaywindow.h new file mode 100644 index 0000000..a83302d --- /dev/null +++ b/src/upgradedelaywindow.h @@ -0,0 +1,28 @@ +#ifndef UPGRADEDELAYWINDOW_H +#define UPGRADEDELAYWINDOW_H + +#include + +namespace Ui { +class UpgradeDelayWindow; +} + +class UpgradeDelayWindow : public QDialog +{ + Q_OBJECT + +public: + explicit UpgradeDelayWindow(QWidget *parent = nullptr); + ~UpgradeDelayWindow(); + qint64 getDelayDays(); + +private slots: + void onOkClicked(); + void onCancelClicked(); + +private: + Ui::UpgradeDelayWindow *ui; + qint64 delayDays; +}; + +#endif // UPGRADEDELAYWINDOW_H diff --git a/src/upgradedelaywindow.ui b/src/upgradedelaywindow.ui new file mode 100644 index 0000000..ea2f0ed --- /dev/null +++ b/src/upgradedelaywindow.ui @@ -0,0 +1,94 @@ + + + UpgradeDelayWindow + + + + 0 + 0 + 457 + 106 + + + + Dialog + + + + + + How long would you like to wait before being reminded of the upgrade again? + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + OK + + + + + + + Cancel + + + + + + + + Days + + + + + Weeks + + + + + Months + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + +