Install update button

This commit is contained in:
Dan Paulat 2024-03-26 22:52:03 -05:00
parent 7012040c32
commit df7b50568d
3 changed files with 131 additions and 11 deletions

View file

@ -1,10 +1,15 @@
#include "update_dialog.hpp"
#include "ui_update_dialog.h"
#include <scwx/qt/main/versions.hpp>
#include <scwx/qt/manager/download_manager.hpp>
#include <scwx/qt/manager/font_manager.hpp>
#include <scwx/qt/ui/download_dialog.hpp>
#include <scwx/util/logger.hpp>
#include <QDesktopServices>
#include <QFontDatabase>
#include <QProcess>
#include <QStandardPaths>
namespace scwx
{
@ -13,19 +18,26 @@ namespace qt
namespace ui
{
class UpdateDialogImpl
static const std::string logPrefix_ = "scwx::qt::ui::update_dialog";
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
class UpdateDialog::Impl
{
public:
explicit UpdateDialogImpl() = default;
~UpdateDialogImpl() = default;
explicit Impl(UpdateDialog* self) : self_ {self} {};
~Impl() = default;
void HandleAsset(const types::gh::ReleaseAsset& asset);
UpdateDialog* self_;
std::string downloadUrl_ {};
std::string installUrl_ {};
std::string installFilename_ {};
};
UpdateDialog::UpdateDialog(QWidget* parent) :
QDialog(parent),
p {std::make_unique<UpdateDialogImpl>()},
ui(new Ui::UpdateDialog)
QDialog(parent), p {std::make_unique<Impl>(this)}, ui(new Ui::UpdateDialog)
{
ui->setupUi(this);
@ -37,6 +49,8 @@ UpdateDialog::UpdateDialog(QWidget* parent) :
ui->bannerLabel->setFont(titleFont);
ui->releaseNotesText->setOpenExternalLinks(true);
ui->installUpdateButton->setVisible(false);
}
UpdateDialog::~UpdateDialog()
@ -56,6 +70,25 @@ void UpdateDialog::UpdateReleaseInfo(const std::string& latestVersion,
QString::fromStdString(latestRelease.body_));
p->downloadUrl_ = latestRelease.htmlUrl_;
ui->installUpdateButton->setVisible(false);
for (auto& asset : latestRelease.assets_)
{
p->HandleAsset(asset);
}
}
void UpdateDialog::Impl::HandleAsset(const types::gh::ReleaseAsset& asset)
{
#if defined(_WIN32)
if (asset.name_.ends_with(".msi"))
{
self_->ui->installUpdateButton->setVisible(true);
installUrl_ = asset.browserDownloadUrl_;
installFilename_ = asset.name_;
}
#endif
}
void UpdateDialog::on_downloadButton_clicked()
@ -66,6 +99,86 @@ void UpdateDialog::on_downloadButton_clicked()
}
}
void UpdateDialog::on_installUpdateButton_clicked()
{
if (!p->installUrl_.empty())
{
ui->installUpdateButton->setEnabled(false);
std::string destinationPath {
QStandardPaths::writableLocation(QStandardPaths::TempLocation)
.toStdString()};
std::shared_ptr<request::DownloadRequest> request =
std::make_shared<request::DownloadRequest>(
p->installUrl_,
std::filesystem::path(destinationPath) / p->installFilename_);
DownloadDialog* downloadDialog = new DownloadDialog(this);
downloadDialog->setAttribute(Qt::WA_DeleteOnClose);
// Connect request signals
connect(request.get(),
&request::DownloadRequest::ProgressUpdated,
downloadDialog,
&DownloadDialog::UpdateProgress);
connect(request.get(),
&request::DownloadRequest::RequestComplete,
downloadDialog,
[=](request::DownloadRequest::CompleteReason reason)
{
switch (reason)
{
case request::DownloadRequest::CompleteReason::OK:
downloadDialog->FinishDownload();
break;
default:
downloadDialog->CancelDownload();
break;
}
});
// Connect dialog signals
connect(
downloadDialog,
&QDialog::accepted,
this,
[=]()
{
std::filesystem::path installerPackage =
request->destination_path();
installerPackage.make_preferred();
logger_->info("Launching application installer: {}",
installerPackage.string());
if (!QProcess::startDetached(
"msiexec.exe",
{"/i", QString::fromStdString(installerPackage.string())}))
{
logger_->error("Failed to launch installer");
}
ui->installUpdateButton->setEnabled(true);
});
connect(downloadDialog,
&QDialog::rejected,
this,
[=]()
{
request->Cancel();
ui->installUpdateButton->setEnabled(true);
});
downloadDialog->set_filename(p->installFilename_);
downloadDialog->StartDownload();
manager::DownloadManager::Instance()->Download(request);
}
}
} // namespace ui
} // namespace qt
} // namespace scwx

View file

@ -16,11 +16,10 @@ namespace qt
namespace ui
{
class UpdateDialogImpl;
class UpdateDialog : public QDialog
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(UpdateDialog)
public:
explicit UpdateDialog(QWidget* parent = nullptr);
@ -31,10 +30,11 @@ public:
private slots:
void on_downloadButton_clicked();
void on_installUpdateButton_clicked();
private:
friend UpdateDialogImpl;
std::unique_ptr<UpdateDialogImpl> p;
class Impl;
std::unique_ptr<Impl> p;
Ui::UpdateDialog* ui;
};

View file

@ -139,6 +139,13 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="installUpdateButton">
<property name="text">
<string>Install Update</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">