181 lines
6.5 KiB
C++
181 lines
6.5 KiB
C++
#define HUMAN_DOWNLOAD_URL "https://bintray.com/cockatrice/Cockatrice/Cockatrice/_latestVersion"
|
|
#define API_DOWNLOAD_BASE_URL "https://dl.bintray.com/cockatrice/Cockatrice/"
|
|
#define DATE_LENGTH 10
|
|
#define MAX_DATE_LENGTH 100
|
|
#define SHORT_SHA1_HASH_LENGTH 7
|
|
|
|
#include <QtNetwork>
|
|
#include <QProgressDialog>
|
|
#include <QDesktopServices>
|
|
#include <QMessageBox>
|
|
#include <QVBoxLayout>
|
|
#include <QDialogButtonBox>
|
|
#include <QPushButton>
|
|
#include <QLabel>
|
|
#include <QProgressBar>
|
|
#include <QApplication>
|
|
|
|
#include "dlg_update.h"
|
|
#include "window_main.h"
|
|
|
|
DlgUpdate::DlgUpdate(QWidget *parent) : QDialog(parent) {
|
|
|
|
//Handle layout
|
|
text = new QLabel(this);
|
|
progress = new QProgressBar(this);
|
|
|
|
QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
|
|
ok = new QPushButton("Ok", this);
|
|
manualDownload = new QPushButton("Update Anyway", this);
|
|
enableUpdateButton(false); //Unless we know there's an update available, you can't install
|
|
gotoDownload = new QPushButton("Open Download Page", this);
|
|
buttonBox->addButton(manualDownload, QDialogButtonBox::ActionRole);
|
|
buttonBox->addButton(gotoDownload, QDialogButtonBox::ActionRole);
|
|
buttonBox->addButton(ok, QDialogButtonBox::AcceptRole);
|
|
|
|
connect(gotoDownload, SIGNAL(clicked()), this, SLOT(gotoDownloadPage()));
|
|
connect(manualDownload, SIGNAL(clicked()), this, SLOT(downloadUpdate()));
|
|
connect(ok, SIGNAL(clicked()), this, SLOT(closeDialog()));
|
|
|
|
QVBoxLayout *parentLayout = new QVBoxLayout(this);
|
|
parentLayout->addWidget(text);
|
|
parentLayout->addWidget(progress);
|
|
parentLayout->addWidget(buttonBox);
|
|
|
|
setLayout(parentLayout);
|
|
|
|
//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, so cannot download updates! "
|
|
"Please visit the download page and update manually."));
|
|
}
|
|
|
|
//Initialize the checker and downloader class
|
|
uDownloader = new UpdateDownloader(this);
|
|
connect(uDownloader, SIGNAL(downloadSuccessful(QUrl)), this, SLOT(downloadSuccessful(QUrl)));
|
|
connect(uDownloader, SIGNAL(progressMade(qint64, qint64)),
|
|
this, SLOT(downloadProgressMade(qint64, qint64)));
|
|
connect(uDownloader, SIGNAL(error(QString)),
|
|
this, SLOT(downloadError(QString)));
|
|
|
|
uChecker = new UpdateChecker(this);
|
|
connect(uChecker, SIGNAL(finishedCheck(bool, bool, QVariantMap * )),
|
|
this, SLOT(finishedUpdateCheck(bool, bool, QVariantMap * )));
|
|
connect(uChecker, SIGNAL(error(QString)),
|
|
this, SLOT(updateCheckError(QString)));
|
|
|
|
//Check for updates
|
|
beginUpdateCheck();
|
|
}
|
|
|
|
|
|
void DlgUpdate::closeDialog() {
|
|
accept();
|
|
}
|
|
|
|
|
|
void DlgUpdate::gotoDownloadPage() {
|
|
QUrl openUrl(HUMAN_DOWNLOAD_URL);
|
|
QDesktopServices::openUrl(openUrl);
|
|
}
|
|
|
|
void DlgUpdate::downloadUpdate() {
|
|
setLabel("Downloading update...");
|
|
enableUpdateButton(false);
|
|
uDownloader->beginDownload(updateUrl);
|
|
}
|
|
|
|
void DlgUpdate::beginUpdateCheck() {
|
|
progress->setMinimum(0);
|
|
progress->setMaximum(0);
|
|
setLabel("Checking for updates...");
|
|
uChecker->check();
|
|
}
|
|
|
|
void DlgUpdate::finishedUpdateCheck(bool needToUpdate, bool isCompatible, QVariantMap *build) {
|
|
|
|
QString commitHash, commitDate;
|
|
|
|
//Update the UI to say we've finished
|
|
progress->setMaximum(100);
|
|
setLabel("Finished checking for updates.");
|
|
|
|
//If there are no available builds, then they can't auto update.
|
|
enableUpdateButton(isCompatible);
|
|
|
|
//If there is an update, save its URL and work out its name
|
|
if (isCompatible) {
|
|
QString endUrl = (*build)["path"].toString();
|
|
updateUrl = API_DOWNLOAD_BASE_URL + endUrl;
|
|
commitHash = (*build)["sha1"].toString().left(SHORT_SHA1_HASH_LENGTH);
|
|
commitDate = (*build)["created"].toString().remove(DATE_LENGTH, MAX_DATE_LENGTH);
|
|
}
|
|
|
|
//Give the user the appropriate message
|
|
if (needToUpdate) {
|
|
if (isCompatible) {
|
|
|
|
QMessageBox::StandardButton reply;
|
|
reply = QMessageBox::question(this, "Update Available",
|
|
"A new build (commit " + commitHash + ") from " + commitDate +
|
|
" is available. Download?",
|
|
QMessageBox::Yes | QMessageBox::No);
|
|
if (reply == QMessageBox::Yes)
|
|
downloadUpdate();
|
|
}
|
|
else {
|
|
QMessageBox::information(this, "Cockatrice Update",
|
|
tr("Your version of Cockatrice is out of date, but there are no packages"
|
|
" available for your operating system. You may have to use a developer build or build from source"
|
|
" yourself. Please visit the download page."));
|
|
}
|
|
}
|
|
else {
|
|
//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("Cockatrice Update"), tr("Your version of Cockatrice is up to date."));
|
|
}
|
|
|
|
}
|
|
|
|
void DlgUpdate::enableUpdateButton(bool enable) {
|
|
manualDownload->setEnabled(enable);
|
|
}
|
|
|
|
void DlgUpdate::setLabel(QString newText) {
|
|
text->setText(newText);
|
|
}
|
|
|
|
void DlgUpdate::updateCheckError(QString errorString) {
|
|
setLabel("Error");
|
|
QMessageBox::critical(this, tr("Update Error"), "An error occurred while checking for updates: " + errorString);
|
|
}
|
|
|
|
void DlgUpdate::downloadError(QString errorString) {
|
|
setLabel("Error");
|
|
enableUpdateButton(true);
|
|
QMessageBox::critical(this, tr("Update Error"), "An error occurred while downloading an update: " + errorString);
|
|
}
|
|
|
|
void DlgUpdate::downloadSuccessful(QUrl filepath) {
|
|
setLabel("Installing...");
|
|
//Try to open the installer. If it opens, quit Cockatrice
|
|
if (QDesktopServices::openUrl(filepath))
|
|
{
|
|
QMetaObject::invokeMethod((MainWindow*) parent(), "close", Qt::QueuedConnection);
|
|
close();
|
|
} else {
|
|
setLabel("Error");
|
|
QMessageBox::critical(this, tr("Update Error"), "Unable to open the installer. You might be able to manually update"
|
|
" by closing Cockatrice and running the installer at " + filepath.toLocalFile() + ".");
|
|
}
|
|
}
|
|
|
|
void DlgUpdate::downloadProgressMade(qint64 bytesRead, qint64 totalBytes) {
|
|
progress->setMaximum(totalBytes);
|
|
progress->setValue(bytesRead);
|
|
}
|