Qt: Support multiple updater channels
This commit is contained in:
parent
14c227a813
commit
7249825c16
|
@ -28,7 +28,7 @@ Log_SetChannel(AutoUpdaterDialog);
|
|||
#ifdef WIN32
|
||||
#if defined(__has_include) && __has_include("scmversion/tag.h")
|
||||
#include "scmversion/tag.h"
|
||||
#ifdef SCM_RELEASE_TAG
|
||||
#ifdef SCM_RELEASE_TAGS
|
||||
#define AUTO_UPDATER_SUPPORTED
|
||||
#endif
|
||||
#endif
|
||||
|
@ -36,11 +36,12 @@ Log_SetChannel(AutoUpdaterDialog);
|
|||
|
||||
#ifdef AUTO_UPDATER_SUPPORTED
|
||||
|
||||
static constexpr char LATEST_TAG_URL[] = "https://api.github.com/repos/stenzek/duckstation/tags";
|
||||
static constexpr char LATEST_RELEASE_URL[] =
|
||||
"https://api.github.com/repos/stenzek/duckstation/releases/tags/" SCM_RELEASE_TAG;
|
||||
static constexpr char CHANGES_URL[] = "https://api.github.com/repos/stenzek/duckstation/compare/%s..." SCM_RELEASE_TAG;
|
||||
static constexpr char UPDATE_ASSET_FILENAME[] = SCM_RELEASE_ASSET;
|
||||
static constexpr char* LATEST_TAG_URL = "https://api.github.com/repos/stenzek/duckstation/tags";
|
||||
static constexpr char* LATEST_RELEASE_URL = "https://api.github.com/repos/stenzek/duckstation/releases/tags/%s";
|
||||
static constexpr char* CHANGES_URL = "https://api.github.com/repos/stenzek/duckstation/compare/%s...%s";
|
||||
static constexpr char* UPDATE_ASSET_FILENAME = SCM_RELEASE_ASSET;
|
||||
static constexpr char* UPDATE_TAGS[] = SCM_RELEASE_TAGS;
|
||||
static constexpr char* THIS_RELEASE_TAG = SCM_RELEASE_TAG;
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -69,6 +70,33 @@ bool AutoUpdaterDialog::isSupported()
|
|||
#endif
|
||||
}
|
||||
|
||||
QStringList AutoUpdaterDialog::getTagList()
|
||||
{
|
||||
#ifdef AUTO_UPDATER_SUPPORTED
|
||||
return QStringList(std::begin(UPDATE_TAGS), std::end(UPDATE_TAGS));
|
||||
#else
|
||||
return QStringList();
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string AutoUpdaterDialog::getDefaultTag()
|
||||
{
|
||||
#ifdef AUTO_UPDATER_SUPPORTED
|
||||
return THIS_RELEASE_TAG;
|
||||
#else
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string AutoUpdaterDialog::getCurrentUpdateTag() const
|
||||
{
|
||||
#ifdef AUTO_UPDATER_SUPPORTED
|
||||
return m_host_interface->GetStringSettingValue("AutoUpdater", "UpdateTag", THIS_RELEASE_TAG);
|
||||
#else
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
void AutoUpdaterDialog::reportError(const char* msg, ...)
|
||||
{
|
||||
std::va_list ap;
|
||||
|
@ -86,7 +114,7 @@ void AutoUpdaterDialog::queueUpdateCheck(bool display_message)
|
|||
#ifdef AUTO_UPDATER_SUPPORTED
|
||||
connect(m_network_access_mgr, &QNetworkAccessManager::finished, this, &AutoUpdaterDialog::getLatestTagComplete);
|
||||
|
||||
QUrl url(QUrl::fromEncoded(QByteArray(LATEST_TAG_URL, sizeof(LATEST_TAG_URL) - 1)));
|
||||
QUrl url(QUrl::fromEncoded(QByteArray(LATEST_TAG_URL)));
|
||||
QNetworkRequest request(url);
|
||||
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||
m_network_access_mgr->get(request);
|
||||
|
@ -100,7 +128,10 @@ void AutoUpdaterDialog::queueGetLatestRelease()
|
|||
#ifdef AUTO_UPDATER_SUPPORTED
|
||||
connect(m_network_access_mgr, &QNetworkAccessManager::finished, this, &AutoUpdaterDialog::getLatestReleaseComplete);
|
||||
|
||||
QUrl url(QUrl::fromEncoded(QByteArray(LATEST_RELEASE_URL, sizeof(LATEST_RELEASE_URL) - 1)));
|
||||
SmallString url_string;
|
||||
url_string.Format(LATEST_RELEASE_URL, getCurrentUpdateTag().c_str());
|
||||
|
||||
QUrl url(QUrl::fromEncoded(QByteArray(url_string)));
|
||||
QNetworkRequest request(url);
|
||||
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||
m_network_access_mgr->get(request);
|
||||
|
@ -110,6 +141,9 @@ void AutoUpdaterDialog::queueGetLatestRelease()
|
|||
void AutoUpdaterDialog::getLatestTagComplete(QNetworkReply* reply)
|
||||
{
|
||||
#ifdef AUTO_UPDATER_SUPPORTED
|
||||
const std::string selected_tag(getCurrentUpdateTag());
|
||||
const QString selected_tag_qstr = QString::fromStdString(selected_tag);
|
||||
|
||||
// this might fail due to a lack of internet connection - in which case, don't spam the user with messages every time.
|
||||
m_network_access_mgr->disconnect(this);
|
||||
reply->deleteLater();
|
||||
|
@ -127,7 +161,7 @@ void AutoUpdaterDialog::getLatestTagComplete(QNetworkReply* reply)
|
|||
if (!val.isObject())
|
||||
continue;
|
||||
|
||||
if (val["name"].toString() != QStringLiteral(SCM_RELEASE_TAG))
|
||||
if (val["name"].toString() != selected_tag_qstr)
|
||||
continue;
|
||||
|
||||
m_latest_sha = val["commit"].toObject()["sha"].toString();
|
||||
|
@ -150,7 +184,7 @@ void AutoUpdaterDialog::getLatestTagComplete(QNetworkReply* reply)
|
|||
}
|
||||
|
||||
if (m_display_messages)
|
||||
reportError("latest release not found in JSON");
|
||||
reportError("%s release not found in JSON", selected_tag.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -228,7 +262,8 @@ void AutoUpdaterDialog::queueGetChanges()
|
|||
#ifdef AUTO_UPDATER_SUPPORTED
|
||||
connect(m_network_access_mgr, &QNetworkAccessManager::finished, this, &AutoUpdaterDialog::getChangesComplete);
|
||||
|
||||
const std::string url_string(StringUtil::StdStringFromFormat(CHANGES_URL, g_scm_hash_str));
|
||||
const std::string url_string(
|
||||
StringUtil::StdStringFromFormat(CHANGES_URL, g_scm_hash_str, getCurrentUpdateTag().c_str()));
|
||||
QUrl url(QUrl::fromEncoded(QByteArray(url_string.c_str(), static_cast<int>(url_string.size()))));
|
||||
QNetworkRequest request(url);
|
||||
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||
|
@ -275,7 +310,7 @@ void AutoUpdaterDialog::getChangesComplete(QNetworkReply* reply)
|
|||
|
||||
if (message.contains(QStringLiteral("[SAVEVERSION+]")))
|
||||
update_will_break_save_states = true;
|
||||
|
||||
|
||||
if (message.contains(QStringLiteral("[SETTINGSVERSION+]")))
|
||||
update_increases_settings_version = true;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
#include "ui_autoupdaterdialog.h"
|
||||
#include <string>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtWidgets/QDialog>
|
||||
|
||||
class QNetworkAccessManager;
|
||||
|
@ -16,6 +18,8 @@ public:
|
|||
~AutoUpdaterDialog();
|
||||
|
||||
static bool isSupported();
|
||||
static QStringList getTagList();
|
||||
static std::string getDefaultTag();
|
||||
|
||||
Q_SIGNALS:
|
||||
void updateCheckCompleted();
|
||||
|
@ -38,6 +42,7 @@ private Q_SLOTS:
|
|||
private:
|
||||
void reportError(const char* msg, ...);
|
||||
bool updateNeeded() const;
|
||||
std::string getCurrentUpdateTag() const;
|
||||
|
||||
#ifdef WIN32
|
||||
bool processUpdate(const QByteArray& update_data);
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#include "generalsettingswidget.h"
|
||||
#include "autoupdaterdialog.h"
|
||||
#include "frontend-common/controller_interface.h"
|
||||
#include "mainwindow.h"
|
||||
#include "qtutils.h"
|
||||
#include "scmversion/scmversion.h"
|
||||
#include "settingsdialog.h"
|
||||
#include "settingwidgetbinder.h"
|
||||
|
||||
|
@ -113,17 +115,28 @@ GeneralSettingsWidget::GeneralSettingsWidget(QtHostInterface* host_interface, QW
|
|||
#endif
|
||||
if (AutoUpdaterDialog::isSupported())
|
||||
{
|
||||
QCheckBox* enableDiscordPresence = new QCheckBox(tr("Enable Automatic Update Check"), m_ui.groupBox_4);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, enableDiscordPresence, "AutoUpdater",
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.autoUpdateEnabled, "AutoUpdater",
|
||||
"CheckAtStartup", true);
|
||||
m_ui.formLayout_4->addWidget(enableDiscordPresence, current_row, current_col);
|
||||
dialog->registerWidgetHelp(enableDiscordPresence, tr("Enable Automatic Update Check"), tr("Checked"),
|
||||
dialog->registerWidgetHelp(m_ui.autoUpdateEnabled, tr("Enable Automatic Update Check"), tr("Checked"),
|
||||
tr("Automatically checks for updates to the program on startup. Updates can be deferred "
|
||||
"until later or skipped entirely."));
|
||||
|
||||
m_ui.autoUpdateTag->addItems(AutoUpdaterDialog::getTagList());
|
||||
SettingWidgetBinder::BindWidgetToStringSetting(m_host_interface, m_ui.autoUpdateTag, "AutoUpdater", "UpdateTag",
|
||||
AutoUpdaterDialog::getDefaultTag());
|
||||
|
||||
m_ui.autoUpdateCurrentVersion->setText(tr("%1 (%2)").arg(g_scm_tag_str).arg(g_scm_date_str));
|
||||
connect(m_ui.checkForUpdates, &QPushButton::clicked,
|
||||
[this]() { m_host_interface->getMainWindow()->checkForUpdates(true); });
|
||||
current_col++;
|
||||
current_row += (current_col / 2);
|
||||
current_col %= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui.verticalLayout->removeWidget(m_ui.automaticUpdaterGroup);
|
||||
m_ui.automaticUpdaterGroup->hide();
|
||||
}
|
||||
}
|
||||
|
||||
GeneralSettingsWidget::~GeneralSettingsWidget() = default;
|
||||
|
|
|
@ -157,6 +157,70 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="automaticUpdaterGroup">
|
||||
<property name="title">
|
||||
<string>Automatic Updater</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Update Channel:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="autoUpdateTag"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Current Version:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="autoUpdateCurrentVersion">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="autoUpdateEnabled">
|
||||
<property name="text">
|
||||
<string>Enable Automatic Update Check</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="checkForUpdates">
|
||||
<property name="text">
|
||||
<string>Check for Updates...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
|
|
|
@ -39,6 +39,8 @@ public Q_SLOTS:
|
|||
/// Updates debug menu visibility (hides if disabled).
|
||||
void updateDebugMenuVisibility();
|
||||
|
||||
void checkForUpdates(bool display_message);
|
||||
|
||||
private Q_SLOTS:
|
||||
void reportError(const QString& message);
|
||||
void reportMessage(const QString& message);
|
||||
|
@ -93,7 +95,6 @@ private Q_SLOTS:
|
|||
void onGameListSetCoverImageRequested(const GameListEntry* entry);
|
||||
void onCPUDebuggerClosed();
|
||||
|
||||
void checkForUpdates(bool display_message);
|
||||
void onUpdateCheckComplete();
|
||||
|
||||
protected:
|
||||
|
|
Loading…
Reference in New Issue