Cockatrice/cockatrice/src/interface/widgets/dialogs/dlg_update.cpp
BruebachL c5fde071e7
[Cleanup] Unused #includes (#6367)
* [Cleanup] Unused #includes

Took 44 minutes

* [Cleanup] More unused #includes

Took 55 minutes

* [Cleanup] Include QSet

Took 4 minutes

* [Cleanup] Include QDebug in deck_list.cpp

Took 3 minutes

* [Cleanup] Include protocol stuff in servatrice_database_interface.h

Took 3 minutes

* [Cleanup] Include QDialogButtonBox

Took 8 minutes

* [Cleanup] Include QUrl

Took 8 minutes

* [Cleanup] Include QTextOption in header.

Took 3 minutes

* [Cleanup] Include QMap in user_list_manager.h

Took 8 minutes

* [Cleanup] Adjust qjson

Took 8 minutes

* [Cleanup] include button box.

Took 3 minutes

* [Cleanup] Redo fwd declarations.

* [Cleanup] Redo last removed fwd declarations.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2025-11-29 18:53:11 +01:00

239 lines
9.1 KiB
C++

#include "dlg_update.h"
#include "../../../client/settings/cache_settings.h"
#include "../client/network/update/client/client_update_checker.h"
#include "../client/network/update/client/release_channel.h"
#include "../interface/window_main.h"
#include <QDesktopServices>
#include <QLabel>
#include <QMessageBox>
#include <QProgressBar>
#include <QPushButton>
#include <QVBoxLayout>
#include <QtNetwork>
#include <version_string.h>
DlgUpdate::DlgUpdate(QWidget *parent) : QDialog(parent)
{
// Handle layout
statusLabel = new QLabel(this);
statusLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
statusLabel->setWordWrap(true);
descriptionLabel =
new QLabel(tr("Current release channel") +
QString(": %1").arg(tr(SettingsCache::instance().getUpdateReleaseChannel()->getName().toUtf8())),
this);
progress = new QProgressBar(this);
buttonBox = new QDialogButtonBox(this);
buttonBox->setFixedWidth(350);
ok = new QPushButton("Close", this);
manualDownload = new QPushButton(tr("Reinstall"), this);
stopDownload = new QPushButton(tr("Cancel Download"), this);
gotoDownload = new QPushButton(tr("Open Download Page"), this);
addStopDownloadAndRemoveOthers(false); // Add all buttons to box
enableUpdateButton(false); // Unless we know there's an update available, you can't install
buttonBox->addButton(ok, QDialogButtonBox::AcceptRole);
connect(gotoDownload, &QPushButton::clicked, this, &DlgUpdate::gotoDownloadPage);
// TODO: make reinstall button actually do something when clicked
// connect(manualDownload, &QPushButton::clicked, this, &DlgUpdate::downloadUpdate);
connect(stopDownload, &QPushButton::clicked, this, &DlgUpdate::cancelDownload);
connect(ok, &QPushButton::clicked, this, &DlgUpdate::closeDialog);
auto *parentLayout = new QVBoxLayout(this);
parentLayout->addWidget(descriptionLabel);
parentLayout->addWidget(statusLabel);
parentLayout->addWidget(progress);
parentLayout->addWidget(buttonBox);
setLayout(parentLayout);
setWindowTitle(tr("Check for Client Updates"));
setFixedHeight(this->sizeHint().height());
setFixedWidth(this->sizeHint().width());
// Check for SSL (this probably isn't necessary)
if (!QSslSocket::supportsSsl()) {
enableUpdateButton(false);
QMessageBox::critical(this, tr("Error"),
tr("Cockatrice was not built with SSL support, therefore you cannot download updates "
"automatically! \nPlease visit the download page to update manually."));
}
// Initialize the checker and downloader class
uDownloader = new UpdateDownloader(this);
connect(uDownloader, &UpdateDownloader::downloadSuccessful, this, &DlgUpdate::downloadSuccessful);
connect(uDownloader, &UpdateDownloader::progressMade, this, &DlgUpdate::downloadProgressMade);
connect(uDownloader, &UpdateDownloader::error, this, &DlgUpdate::downloadError);
// Check for updates
beginUpdateCheck();
}
void DlgUpdate::closeDialog()
{
accept();
}
void DlgUpdate::gotoDownloadPage()
{
QDesktopServices::openUrl(SettingsCache::instance().getUpdateReleaseChannel()->getManualDownloadUrl());
}
void DlgUpdate::downloadUpdate(const QString &releaseName)
{
setLabel(tr("Downloading update: %1").arg(releaseName));
addStopDownloadAndRemoveOthers(true); // Will remove all other buttons
uDownloader->beginDownload(updateUrl);
}
void DlgUpdate::cancelDownload()
{
emit uDownloader->stopDownload();
setLabel("Download canceled");
addStopDownloadAndRemoveOthers(false);
downloadProgressMade(0, 1);
}
void DlgUpdate::beginUpdateCheck()
{
progress->setMinimum(0);
progress->setMaximum(0);
setLabel(tr("Checking for updates..."));
auto checker = new ClientUpdateChecker(this);
connect(checker, &ClientUpdateChecker::finishedCheck, this, &DlgUpdate::finishedUpdateCheck);
connect(checker, &ClientUpdateChecker::error, this, &DlgUpdate::updateCheckError);
checker->check();
}
void DlgUpdate::finishedUpdateCheck(bool needToUpdate, bool isCompatible, Release *release)
{
QString publishDate, versionName;
// Update the UI to say we've finished
progress->setMaximum(100);
setLabel(tr("Finished checking for updates"));
// If there are no available builds, then they can't auto update.
enableUpdateButton(isCompatible);
if (isCompatible) {
// If there is an update, save its URL and work out its name
updateUrl = release->getDownloadUrl();
}
// Give the user the appropriate message
if (!needToUpdate) {
// If there's no need to update, tell them that. However we still allow them to run the
// downloader themselves if there's a compatible build
QMessageBox::information(
this, tr("No Update Available"),
tr("Cockatrice is up to date!") + "<br><br>" +
tr("You are already running the latest version available in the chosen release channel.") + "<br>" +
"<b>" + tr("Current version") + QString(":</b> %1<br>").arg(VERSION_STRING) + "<b>" +
tr("Selected release channel") +
QString(":</b> %1").arg(tr(SettingsCache::instance().getUpdateReleaseChannel()->getName().toUtf8())));
return;
}
publishDate = release->getPublishDate().toString(QLocale().dateFormat(QLocale::LongFormat));
if (isCompatible) {
int reply;
reply = QMessageBox::question(
this, tr("Update Available"),
tr("A new version of Cockatrice is available!") + "<br><br>" + "<b>" + tr("New version") +
QString(":</b> %1<br>").arg(release->getName()) + "<b>" + tr("Released") +
QString(":</b> %1 (<a href=\"%2\">").arg(publishDate, release->getDescriptionUrl()) + tr("Changelog") +
"</a>)<br><br>" + tr("Do you want to update now?"),
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes)
downloadUpdate(release->getName());
} else {
QMessageBox::information(
this, tr("Update Available"),
tr("A new version of Cockatrice is available!") + "<br><br>" + "<b>" + tr("New version") +
QString(":</b> %1<br>").arg(release->getName()) + "<b>" + tr("Released") +
QString(":</b> %1 (<a href=\"%2\">").arg(publishDate, release->getDescriptionUrl()) + tr("Changelog") +
"</a>)<br><br>" +
tr("Unfortunately, the automatic updater failed to find a compatible download. \nYou may have to "
"manually download the new version.") +
"<br><br>" +
tr("Please check the <a href=\"%1\">releases page</a> on our Github and download the build for your "
"system.")
.arg(release->getDescriptionUrl()));
}
}
void DlgUpdate::enableUpdateButton(bool enable)
{
manualDownload->setEnabled(enable);
}
void DlgUpdate::addStopDownloadAndRemoveOthers(bool enable)
{
if (enable) {
buttonBox->addButton(stopDownload, QDialogButtonBox::ActionRole);
buttonBox->removeButton(manualDownload);
buttonBox->removeButton(gotoDownload);
} else {
buttonBox->removeButton(stopDownload);
buttonBox->addButton(manualDownload, QDialogButtonBox::ActionRole);
buttonBox->addButton(gotoDownload, QDialogButtonBox::ActionRole);
}
}
void DlgUpdate::enableOkButton(bool enable)
{
ok->setEnabled(enable);
}
void DlgUpdate::setLabel(const QString &newText)
{
statusLabel->setText(newText);
}
void DlgUpdate::updateCheckError(const QString &errorString)
{
setLabel(tr("Error"));
QMessageBox::critical(this, tr("Update Error"),
tr("An error occurred while checking for updates:") + QString(" ") + errorString);
}
void DlgUpdate::downloadError(const QString &errorString)
{
setLabel(tr("Error"));
enableUpdateButton(true);
QMessageBox::critical(this, tr("Update Error"),
tr("An error occurred while downloading an update:") + QString(" ") + errorString);
}
void DlgUpdate::downloadSuccessful(const QUrl &filepath)
{
setLabel(tr("Installing..."));
// Try to open the installer. If it opens, quit Cockatrice
if (QDesktopServices::openUrl(filepath)) {
QMetaObject::invokeMethod(static_cast<MainWindow *>(parent()), "close", Qt::QueuedConnection);
qCInfo(DlgUpdateLog) << "Opened downloaded update file successfully - closing Cockatrice";
close();
} else {
setLabel(tr("Error"));
QMessageBox::critical(this, tr("Update Error"),
tr("Cockatrice is unable to open the installer.") + "<br><br>" +
tr("Try to update manually by closing Cockatrice and running the installer.") +
"<br>" + tr("Download location") + QString(": %1").arg(filepath.toLocalFile()));
}
}
void DlgUpdate::downloadProgressMade(qint64 bytesRead, qint64 totalBytes)
{
progress->setMaximum(totalBytes);
progress->setValue(bytesRead);
}