Merge pull request #6489 from spycrab/qt_updater
Qt: Improve and better integrate updater
This commit is contained in:
commit
773ec975f3
|
@ -117,6 +117,7 @@ set(SRCS
|
|||
TAS/Shared.cpp
|
||||
TAS/StickWidget.cpp
|
||||
TAS/IRWidget.cpp
|
||||
Updater.cpp
|
||||
)
|
||||
|
||||
list(APPEND LIBS core uicommon)
|
||||
|
|
|
@ -127,6 +127,7 @@
|
|||
<QtMoc Include="Settings\AdvancedPane.h" />
|
||||
<QtMoc Include="Settings\GeneralPane.h" />
|
||||
<QtMoc Include="ToolBar.h" />
|
||||
<QtMoc Include="Updater.h" />
|
||||
</ItemGroup>
|
||||
<!--TODO figure out how to get QtMoc to add outputs to ClCompile's inputs...-->
|
||||
<ItemGroup>
|
||||
|
@ -196,6 +197,7 @@
|
|||
<ClCompile Include="$(QtMocOutPrefix)ToolBar.cpp" />
|
||||
<ClCompile Include="$(QtMocOutPrefix)WatchWidget.cpp" />
|
||||
<ClCompile Include="$(QtMocOutPrefix)USBDeviceAddToWhitelistDialog.cpp" />
|
||||
<ClCompile Include="$(QtMocOutPrefix)Updater.cpp" />
|
||||
<ClCompile Include="AboutDialog.cpp" />
|
||||
<ClCompile Include="Config\CheatCodeEditor.cpp" />
|
||||
<ClCompile Include="Config\ARCodeWidget.cpp" />
|
||||
|
@ -294,6 +296,7 @@
|
|||
<ClCompile Include="Settings\USBDeviceAddToWhitelistDialog.cpp" />
|
||||
<ClCompile Include="ToolBar.cpp" />
|
||||
<ClCompile Include="Translation.cpp" />
|
||||
<ClCompile Include="Updater.cpp" />
|
||||
<ClCompile Include="WiiUpdate.cpp" />
|
||||
</ItemGroup>
|
||||
<!--Put standard C/C++ headers here. Headers that are listed in the QtMoc ItemGroup must NOT be listed here.-->
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "DolphinQt2/Resources.h"
|
||||
#include "DolphinQt2/Settings.h"
|
||||
#include "DolphinQt2/Translation.h"
|
||||
#include "UICommon/AutoUpdate.h"
|
||||
#include "DolphinQt2/Updater.h"
|
||||
#include "UICommon/CommandLineParse.h"
|
||||
#include "UICommon/UICommon.h"
|
||||
|
||||
|
@ -63,35 +63,6 @@ static bool QtMsgAlertHandler(const char* caption, const char* text, bool yes_no
|
|||
});
|
||||
}
|
||||
|
||||
// TODO: This should be replaced with something in a background thread, it performs a blocking
|
||||
// HTTP query. It also needs a proper UI, and many other things. But right now it needs to be
|
||||
// manually enabled through INI, so all these problems are ignored :)
|
||||
class QtAutoUpdateChecker : public AutoUpdateChecker
|
||||
{
|
||||
public:
|
||||
explicit QtAutoUpdateChecker(QWidget* parent) : m_parent(parent) {}
|
||||
protected:
|
||||
void OnUpdateAvailable(const NewVersionInformation& info) override
|
||||
{
|
||||
QMessageBox prompt(m_parent);
|
||||
|
||||
prompt.setIcon(QMessageBox::Question);
|
||||
prompt.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
prompt.setText(QString::fromUtf8("Update Dolphin to version %1?")
|
||||
.arg(QString::fromStdString(info.new_shortrev)));
|
||||
|
||||
const int answer = prompt.exec();
|
||||
if (answer == QMessageBox::Yes)
|
||||
{
|
||||
TriggerUpdate(info);
|
||||
m_parent->close();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QWidget* m_parent;
|
||||
};
|
||||
|
||||
// N.B. On Windows, this should be called from WinMain. Link against qtmain and specify
|
||||
// /SubSystem:Windows
|
||||
int main(int argc, char* argv[])
|
||||
|
@ -188,8 +159,8 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
#endif
|
||||
|
||||
QtAutoUpdateChecker updater(&win);
|
||||
updater.CheckForUpdate();
|
||||
auto* updater = new Updater(&win);
|
||||
updater->start();
|
||||
|
||||
retval = app.exec();
|
||||
}
|
||||
|
|
|
@ -312,3 +312,18 @@ QFont Settings::GetDebugFont() const
|
|||
|
||||
return QSettings().value(QStringLiteral("debugger/font"), default_font).value<QFont>();
|
||||
}
|
||||
|
||||
void Settings::SetAutoUpdateTrack(const QString& mode)
|
||||
{
|
||||
if (mode == GetAutoUpdateTrack())
|
||||
return;
|
||||
|
||||
SConfig::GetInstance().m_auto_update_track = mode.toStdString();
|
||||
|
||||
emit AutoUpdateTrackChanged(mode);
|
||||
}
|
||||
|
||||
QString Settings::GetAutoUpdateTrack() const
|
||||
{
|
||||
return QString::fromStdString(SConfig::GetInstance().m_auto_update_track);
|
||||
}
|
||||
|
|
|
@ -98,6 +98,10 @@ public:
|
|||
QFont GetDebugFont() const;
|
||||
void SetDebugFont(QFont font);
|
||||
|
||||
// Auto-Update
|
||||
QString GetAutoUpdateTrack() const;
|
||||
void SetAutoUpdateTrack(const QString& mode);
|
||||
|
||||
// Other
|
||||
GameListModel* GetGameListModel() const;
|
||||
signals:
|
||||
|
@ -119,6 +123,7 @@ signals:
|
|||
void CodeVisibilityChanged(bool visible);
|
||||
void DebugModeToggled(bool enabled);
|
||||
void DebugFontChanged(QFont font);
|
||||
void AutoUpdateTrackChanged(const QString& mode);
|
||||
|
||||
private:
|
||||
bool m_controller_state_needed = false;
|
||||
|
|
|
@ -20,6 +20,17 @@
|
|||
#include "Core/ConfigManager.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
#include "DolphinQt2/Settings.h"
|
||||
#include "UICommon/AutoUpdate.h"
|
||||
|
||||
constexpr int AUTO_UPDATE_DISABLE_INDEX = 0;
|
||||
constexpr int AUTO_UPDATE_STABLE_INDEX = 1;
|
||||
constexpr int AUTO_UPDATE_BETA_INDEX = 2;
|
||||
constexpr int AUTO_UPDATE_DEV_INDEX = 3;
|
||||
|
||||
constexpr const char* AUTO_UPDATE_DISABLE_STRING = "";
|
||||
constexpr const char* AUTO_UPDATE_STABLE_STRING = "stable";
|
||||
constexpr const char* AUTO_UPDATE_BETA_STRING = "beta";
|
||||
constexpr const char* AUTO_UPDATE_DEV_STRING = "dev";
|
||||
|
||||
GeneralPane::GeneralPane(QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
|
@ -34,6 +45,10 @@ void GeneralPane::CreateLayout()
|
|||
m_main_layout = new QVBoxLayout;
|
||||
// Create layout here
|
||||
CreateBasic();
|
||||
|
||||
if (AutoUpdateChecker::SystemSupportsAutoUpdates())
|
||||
CreateAutoUpdate();
|
||||
|
||||
#if defined(USE_ANALYTICS) && USE_ANALYTICS
|
||||
CreateAnalytics();
|
||||
#endif
|
||||
|
@ -48,6 +63,16 @@ void GeneralPane::ConnectLayout()
|
|||
{
|
||||
connect(m_checkbox_dualcore, &QCheckBox::clicked, this, &GeneralPane::OnSaveConfig);
|
||||
connect(m_checkbox_cheats, &QCheckBox::clicked, this, &GeneralPane::OnSaveConfig);
|
||||
|
||||
if (AutoUpdateChecker::SystemSupportsAutoUpdates())
|
||||
{
|
||||
connect(m_combobox_update_track,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
||||
&GeneralPane::OnSaveConfig);
|
||||
connect(&Settings::Instance(), &Settings::AutoUpdateTrackChanged, this,
|
||||
&GeneralPane::LoadConfig);
|
||||
}
|
||||
|
||||
// Advanced
|
||||
connect(m_combobox_speedlimit,
|
||||
static_cast<void (QComboBox::*)(const QString&)>(&QComboBox::activated),
|
||||
|
@ -96,6 +121,22 @@ void GeneralPane::CreateBasic()
|
|||
speed_limit_layout->addRow(tr("&Speed Limit:"), m_combobox_speedlimit);
|
||||
}
|
||||
|
||||
void GeneralPane::CreateAutoUpdate()
|
||||
{
|
||||
auto* auto_update_group = new QGroupBox(tr("Auto Update Settings"));
|
||||
auto* layout = new QFormLayout;
|
||||
auto_update_group->setLayout(layout);
|
||||
m_main_layout->addWidget(auto_update_group);
|
||||
|
||||
m_combobox_update_track = new QComboBox(this);
|
||||
|
||||
layout->addRow(tr("&Auto Update:"), m_combobox_update_track);
|
||||
|
||||
for (const QString& option : {tr("Don't Update"), tr("Stable (once a year)"),
|
||||
tr("Beta (once a month)"), tr("Dev (multiple times a day)")})
|
||||
m_combobox_update_track->addItem(option);
|
||||
}
|
||||
|
||||
#if defined(USE_ANALYTICS) && USE_ANALYTICS
|
||||
void GeneralPane::CreateAnalytics()
|
||||
{
|
||||
|
@ -135,6 +176,20 @@ void GeneralPane::CreateAdvanced()
|
|||
|
||||
void GeneralPane::LoadConfig()
|
||||
{
|
||||
if (AutoUpdateChecker::SystemSupportsAutoUpdates())
|
||||
{
|
||||
const auto track = Settings::Instance().GetAutoUpdateTrack().toStdString();
|
||||
|
||||
if (track == AUTO_UPDATE_DISABLE_STRING)
|
||||
m_combobox_update_track->setCurrentIndex(AUTO_UPDATE_DISABLE_INDEX);
|
||||
else if (track == AUTO_UPDATE_STABLE_STRING)
|
||||
m_combobox_update_track->setCurrentIndex(AUTO_UPDATE_STABLE_INDEX);
|
||||
else if (track == AUTO_UPDATE_BETA_STRING)
|
||||
m_combobox_update_track->setCurrentIndex(AUTO_UPDATE_BETA_INDEX);
|
||||
else
|
||||
m_combobox_update_track->setCurrentIndex(AUTO_UPDATE_DEV_INDEX);
|
||||
}
|
||||
|
||||
#if defined(USE_ANALYTICS) && USE_ANALYTICS
|
||||
m_checkbox_enable_analytics->setChecked(SConfig::GetInstance().m_analytics_enabled);
|
||||
#endif
|
||||
|
@ -164,8 +219,37 @@ void GeneralPane::LoadConfig()
|
|||
}
|
||||
}
|
||||
|
||||
static QString UpdateTrackFromIndex(int index)
|
||||
{
|
||||
QString value;
|
||||
|
||||
switch (index)
|
||||
{
|
||||
case AUTO_UPDATE_DISABLE_INDEX:
|
||||
value = QString::fromStdString(AUTO_UPDATE_DISABLE_STRING);
|
||||
break;
|
||||
case AUTO_UPDATE_STABLE_INDEX:
|
||||
value = QString::fromStdString(AUTO_UPDATE_STABLE_STRING);
|
||||
break;
|
||||
case AUTO_UPDATE_BETA_INDEX:
|
||||
value = QString::fromStdString(AUTO_UPDATE_BETA_STRING);
|
||||
break;
|
||||
case AUTO_UPDATE_DEV_INDEX:
|
||||
value = QString::fromStdString(AUTO_UPDATE_DEV_STRING);
|
||||
break;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void GeneralPane::OnSaveConfig()
|
||||
{
|
||||
if (AutoUpdateChecker::SystemSupportsAutoUpdates())
|
||||
{
|
||||
Settings::Instance().SetAutoUpdateTrack(
|
||||
UpdateTrackFromIndex(m_combobox_update_track->currentIndex()));
|
||||
}
|
||||
|
||||
#if defined(USE_ANALYTICS) && USE_ANALYTICS
|
||||
SConfig::GetInstance().m_analytics_enabled = m_checkbox_enable_analytics->isChecked();
|
||||
#endif
|
||||
|
|
|
@ -24,6 +24,7 @@ private:
|
|||
void CreateLayout();
|
||||
void ConnectLayout();
|
||||
void CreateBasic();
|
||||
void CreateAutoUpdate();
|
||||
void CreateAdvanced();
|
||||
|
||||
void LoadConfig();
|
||||
|
@ -32,6 +33,7 @@ private:
|
|||
// Widgets
|
||||
QVBoxLayout* m_main_layout;
|
||||
QComboBox* m_combobox_speedlimit;
|
||||
QComboBox* m_combobox_update_track;
|
||||
QCheckBox* m_checkbox_dualcore;
|
||||
QCheckBox* m_checkbox_cheats;
|
||||
QLabel* m_label_speedlimit;
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
// Copyright 2018 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "DolphinQt2/Updater.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QTextBrowser>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "Common/Version.h"
|
||||
#include "DolphinQt2/QtUtils/RunOnObject.h"
|
||||
#include "DolphinQt2/Settings.h"
|
||||
|
||||
Updater::Updater(QWidget* parent) : m_parent(parent)
|
||||
{
|
||||
connect(this, &QThread::finished, this, &QObject::deleteLater);
|
||||
}
|
||||
|
||||
void Updater::run()
|
||||
{
|
||||
CheckForUpdate();
|
||||
}
|
||||
|
||||
void Updater::OnUpdateAvailable(const NewVersionInformation& info)
|
||||
{
|
||||
bool later = false;
|
||||
|
||||
int choice = RunOnObject(m_parent, [&] {
|
||||
QDialog* dialog = new QDialog(m_parent);
|
||||
dialog->setWindowTitle(tr("Update available"));
|
||||
|
||||
auto* label = new QLabel(
|
||||
tr("<h2>A new version of Dolphin is available!</h2>Dolphin %1 is available for "
|
||||
"download. "
|
||||
"You are running %2.<br> Would you like to update?<br><h4>Release Notes:</h4>")
|
||||
.arg(QString::fromStdString(info.new_shortrev))
|
||||
.arg(QString::fromStdString(Common::scm_desc_str)));
|
||||
label->setTextFormat(Qt::RichText);
|
||||
|
||||
auto* changelog = new QTextBrowser;
|
||||
|
||||
changelog->setHtml(QString::fromStdString(info.changelog_html));
|
||||
changelog->setOpenExternalLinks(true);
|
||||
changelog->setMinimumWidth(400);
|
||||
|
||||
auto* update_later_check = new QCheckBox(tr("Update after closing Dolphin"));
|
||||
|
||||
connect(update_later_check, &QCheckBox::toggled, [&](bool checked) { later = checked; });
|
||||
|
||||
auto* buttons = new QDialogButtonBox;
|
||||
|
||||
auto* never_btn =
|
||||
buttons->addButton(tr("Never Auto-Update"), QDialogButtonBox::DestructiveRole);
|
||||
buttons->addButton(tr("Remind Me Later"), QDialogButtonBox::RejectRole);
|
||||
buttons->addButton(tr("Install Update"), QDialogButtonBox::AcceptRole);
|
||||
|
||||
auto* layout = new QVBoxLayout;
|
||||
dialog->setLayout(layout);
|
||||
|
||||
layout->addWidget(label);
|
||||
layout->addWidget(changelog);
|
||||
layout->addWidget(update_later_check);
|
||||
layout->addWidget(buttons);
|
||||
|
||||
connect(never_btn, &QPushButton::pressed, [dialog] {
|
||||
Settings::Instance().SetAutoUpdateTrack(QStringLiteral(""));
|
||||
dialog->reject();
|
||||
});
|
||||
|
||||
connect(buttons, &QDialogButtonBox::accepted, dialog, &QDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, dialog, &QDialog::reject);
|
||||
|
||||
return dialog->exec();
|
||||
});
|
||||
|
||||
if (choice == QDialog::Accepted)
|
||||
{
|
||||
TriggerUpdate(info);
|
||||
|
||||
if (!later)
|
||||
m_parent->close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright 2018 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QThread>
|
||||
|
||||
#include "UICommon/AutoUpdate.h"
|
||||
|
||||
class QWidget;
|
||||
|
||||
class Updater : public QThread, public AutoUpdateChecker
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Updater(QWidget* parent);
|
||||
|
||||
void run() override;
|
||||
void OnUpdateAvailable(const NewVersionInformation& info) override;
|
||||
|
||||
private:
|
||||
QWidget* m_parent;
|
||||
};
|
|
@ -20,15 +20,6 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
bool SystemSupportsAutoUpdates()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
const char UPDATER_FILENAME[] = "Updater.exe";
|
||||
|
@ -57,10 +48,19 @@ void CleanupFromPreviousUpdate()
|
|||
#endif
|
||||
} // namespace
|
||||
|
||||
bool AutoUpdateChecker::SystemSupportsAutoUpdates()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void AutoUpdateChecker::CheckForUpdate()
|
||||
{
|
||||
// Don't bother checking if updates are not supported or not enabled.
|
||||
if (SConfig::GetInstance().m_auto_update_track.empty() || !SystemSupportsAutoUpdates())
|
||||
if (!SystemSupportsAutoUpdates() || SConfig::GetInstance().m_auto_update_track.empty())
|
||||
return;
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -104,7 +104,10 @@ void AutoUpdateChecker::CheckForUpdate()
|
|||
nvi.content_store_url = obj["content-store"].get<std::string>();
|
||||
nvi.new_shortrev = obj["new"].get<picojson::object>()["name"].get<std::string>();
|
||||
nvi.new_hash = obj["new"].get<picojson::object>()["hash"].get<std::string>();
|
||||
|
||||
// TODO: generate the HTML changelog from the JSON information.
|
||||
nvi.changelog_html = "<h2>TBD</h2>";
|
||||
|
||||
OnUpdateAvailable(nvi);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@ public:
|
|||
// update is available, does "nothing" otherwise.
|
||||
void CheckForUpdate();
|
||||
|
||||
static bool SystemSupportsAutoUpdates();
|
||||
|
||||
struct NewVersionInformation
|
||||
{
|
||||
// Name (5.0-1234) and revision hash of the new version.
|
||||
|
|
Loading…
Reference in New Issue