Skip to content

Commit

Permalink
Implement custom upgrade notification dialog box
Browse files Browse the repository at this point in the history
Also allow updatedialog to be called from About Gridcoin
  • Loading branch information
jamescowens committed Feb 19, 2024
1 parent 871aad2 commit a674f0f
Show file tree
Hide file tree
Showing 18 changed files with 368 additions and 64 deletions.
4 changes: 4 additions & 0 deletions src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ QT_FORMS_UI = \
qt/forms/sendcoinsentry.ui \
qt/forms/signverifymessagedialog.ui \
qt/forms/transactiondescdialog.ui \
qt/forms/updatedialog.ui \
qt/forms/voting/additionalfieldstableview.ui \
qt/forms/voting/pollcard.ui \
qt/forms/voting/pollcardview.ui \
Expand Down Expand Up @@ -171,6 +172,7 @@ QT_MOC_CPP = \
qt/moc_transactionfilterproxy.cpp \
qt/moc_transactiontablemodel.cpp \
qt/moc_transactionview.cpp \
qt/moc_updatedialog.cpp \
qt/moc_walletmodel.cpp \
qt/researcher/moc_projecttablemodel.cpp \
qt/researcher/moc_researchermodel.cpp \
Expand Down Expand Up @@ -298,6 +300,7 @@ GRIDCOINRESEARCH_QT_H = \
qt/transactionrecord.h \
qt/transactiontablemodel.h \
qt/transactionview.h \
qt/updatedialog.h \
qt/upgradeqt.h \
qt/voting/additionalfieldstableview.h \
qt/voting/additionalfieldstablemodel.h \
Expand Down Expand Up @@ -388,6 +391,7 @@ GRIDCOINRESEARCH_QT_CPP = \
qt/transactiontablemodel.cpp \
qt/transactionview.cpp \
qt/upgradeqt.cpp \
qt/updatedialog.cpp \
qt/voting/additionalfieldstableview.cpp \
qt/voting/additionalfieldstablemodel.cpp \
qt/voting/poll_types.cpp \
Expand Down
115 changes: 73 additions & 42 deletions src/gridcoin/upgrade.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,16 @@ Upgrade::Upgrade()

void Upgrade::ScheduledUpdateCheck()
{
std::string VersionResponse = "";
std::string VersionResponse;
std::string change_log;

Upgrade::UpgradeType upgrade_type {Upgrade::UpgradeType::Unknown};

CheckForLatestUpdate(VersionResponse);
CheckForLatestUpdate(VersionResponse, change_log, upgrade_type);
}

bool Upgrade::CheckForLatestUpdate(std::string& client_message_out, bool ui_dialog, bool snapshotrequest)
bool Upgrade::CheckForLatestUpdate(std::string& client_message_out, std::string& change_log, Upgrade::UpgradeType& upgrade_type,
bool ui_dialog, bool snapshotrequest)
{
// If testnet skip this || If the user changes this to disable while wallet running just drop out of here now.
// (Need a way to remove items from scheduler.)
Expand All @@ -46,8 +50,8 @@ bool Upgrade::CheckForLatestUpdate(std::string& client_message_out, bool ui_dial

Http VersionPull;

std::string GithubResponse = "";
std::string VersionResponse = "";
std::string GithubResponse;
std::string VersionResponse;

// We receive the response and it's in a json reply
UniValue Response(UniValue::VOBJ);
Expand All @@ -64,15 +68,15 @@ bool Upgrade::CheckForLatestUpdate(std::string& client_message_out, bool ui_dial

if (VersionResponse.empty())
{
LogPrintf("WARNING %s: No Response from GitHub", __func__);
LogPrintf("WARNING: %s: No Response from GitHub", __func__);

return false;
}

std::string GithubReleaseData = "";
std::string GithubReleaseTypeData = "";
std::string GithubReleaseBody = "";
std::string GithubReleaseType = "";
std::string GithubReleaseData;
std::string GithubReleaseTypeData;
std::string GithubReleaseBody;
std::string GithubReleaseType;

try
{
Expand All @@ -95,14 +99,19 @@ bool Upgrade::CheckForLatestUpdate(std::string& client_message_out, bool ui_dial
}

GithubReleaseTypeData = ToLower(GithubReleaseTypeData);
if (GithubReleaseTypeData.find("leisure") != std::string::npos)
GithubReleaseType = _("leisure");

else if (GithubReleaseTypeData.find("mandatory") != std::string::npos)
if (GithubReleaseTypeData.find("leisure") != std::string::npos) {
GithubReleaseType = _("leisure");
upgrade_type = Upgrade::UpgradeType::Leisure;
} else if (GithubReleaseTypeData.find("mandatory") != std::string::npos) {
GithubReleaseType = _("mandatory");

else
// This will be confirmed below by also checking the second position version. If not incremented, then it will
// be set to unknown.
upgrade_type = Upgrade::UpgradeType::Mandatory;
} else {
GithubReleaseType = _("unknown");
upgrade_type = Upgrade::UpgradeType::Unknown;
}

// Parse version data
std::vector<std::string> GithubVersion;
Expand All @@ -113,6 +122,7 @@ bool Upgrade::CheckForLatestUpdate(std::string& client_message_out, bool ui_dial
LocalVersion.push_back(CLIENT_VERSION_MAJOR);
LocalVersion.push_back(CLIENT_VERSION_MINOR);
LocalVersion.push_back(CLIENT_VERSION_REVISION);
LocalVersion.push_back(CLIENT_VERSION_BUILD);

if (GithubVersion.size() != 4)
{
Expand All @@ -123,60 +133,79 @@ bool Upgrade::CheckForLatestUpdate(std::string& client_message_out, bool ui_dial

bool NewVersion = false;
bool NewMandatory = false;
bool same_version = true;

try {
// Left to right version numbers.
// 3 numbers to check for production.
for (unsigned int x = 0; x < 3; x++)
{
// 4 numbers to check.
for (unsigned int x = 0; x <= 3; x++) {
int github_version = 0;

if (!ParseInt32(GithubVersion[x], &github_version))
{
if (!ParseInt32(GithubVersion[x], &github_version)) {
throw std::invalid_argument("Failed to parse GitHub version from official GitHub project repo.");
}

if (github_version > LocalVersion[x])
{
if (github_version > LocalVersion[x]) {
NewVersion = true;
if (x < 2)
{
same_version = false;

if (x < 2 && upgrade_type == Upgrade::UpgradeType::Mandatory) {
NewMandatory = true;
} else {
upgrade_type = Upgrade::UpgradeType::Unknown;
}
break;
} else {
same_version &= (github_version == LocalVersion[x]);
}
}
}
catch (std::exception& ex)
{
} catch (std::exception& ex) {
error("%s: Exception occurred checking client version against GitHub version (%s)",
__func__, ToString(ex.what()));

upgrade_type = Upgrade::UpgradeType::Unknown;
return false;
}

if (!NewVersion) return NewVersion;

// New version was found
// Populate client_message_out regardless of whether new version is found, because we are using this method for
// the version information button in the "About Gridcoin" dialog.
client_message_out = _("Local version: ") + strprintf("%d.%d.%d.%d", CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR,
CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD) + "\r\n";
client_message_out.append(_("GitHub version: ") + GithubReleaseData + "\r\n");
client_message_out.append(_("This update is ") + GithubReleaseType + "\r\n\r\n");

// For snapshot requests we will handle things differently after this point
if (snapshotrequest && NewMandatory)
return NewVersion;
if (NewVersion) {
client_message_out.append(_("This update is ") + GithubReleaseType + "\r\n\r\n");
} else if (same_version) {
client_message_out.append(_("The latest release is ") + GithubReleaseType + "\r\n\r\n");
client_message_out.append(_("You are running the latest release.") + "\n");
} else {
client_message_out.append(_("The latest release is ") + GithubReleaseType + "\r\n\r\n");

// If not a new version available and the version is not the same, the only thing left is that we are running
// a version greater than the latest release version, so set the upgrade_type to Unsupported, which is used for a
// warning.
upgrade_type = Upgrade::UpgradeType::Unsupported;
client_message_out.append(_("WARNING: You are running a version that is higher than the latest release.") + "\n");
}

change_log = GithubReleaseBody;

if (!NewVersion) return false;

if (NewMandatory)
// For snapshot requests we will only return true if there is a new mandatory version AND the snapshotrequest boolean
// is set true. This is because the snapshot request context is looking for the presence of a new mandatory to block
// the snapshot download before upgrading to the new mandatory if there is one.
if (snapshotrequest && NewMandatory) return true;

if (NewMandatory) {
client_message_out.append(_("WARNING: A mandatory release is available. Please upgrade as soon as possible.")
+ "\n");
}

std::string ChangeLog = GithubReleaseBody;

if (ui_dialog)
uiInterface.UpdateMessageBox(client_message_out, ChangeLog);
if (ui_dialog) {
uiInterface.UpdateMessageBox(client_message_out, static_cast<int>(upgrade_type), change_log);
}

return NewVersion;
return true;
}

void Upgrade::SnapshotMain()
Expand All @@ -188,8 +217,10 @@ void Upgrade::SnapshotMain()

// Verify a mandatory release is not available before we continue to snapshot download.
std::string VersionResponse = "";
std::string change_log;
Upgrade::UpgradeType upgrade_type {Upgrade::UpgradeType::Unknown};

if (CheckForLatestUpdate(VersionResponse, false, true))
if (CheckForLatestUpdate(VersionResponse, change_log, upgrade_type, false, true))
{
std::cout << this->ResetBlockchainMessages(UpdateAvailable) << std::endl;
std::cout << this->ResetBlockchainMessages(GithubResponse) << std::endl;
Expand Down
10 changes: 9 additions & 1 deletion src/gridcoin/upgrade.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ class Upgrade
GithubResponse
};

enum UpgradeType {
Unknown,
Leisure,
Mandatory,
Unsupported //! This is used for a running version that is greater than the current official release.
};

//!
//! \brief Scheduler call to CheckForLatestUpdate
//!
Expand All @@ -133,7 +140,8 @@ class Upgrade
//!
//! \brief Check for latest updates on GitHub.
//!
static bool CheckForLatestUpdate(std::string& client_message_out, bool ui_dialog = true, bool snapshotrequest = false);
static bool CheckForLatestUpdate(std::string& client_message_out, std::string& change_log, UpgradeType& upgrade_type,
bool ui_dialog = true, bool snapshotrequest = false);

//!
//! \brief Function that will be threaded to download snapshot
Expand Down
2 changes: 1 addition & 1 deletion src/node/ui_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ ADD_SIGNALS_IMPL_WRAPPER(UpdateMessageBox);
ADD_SIGNALS_IMPL_WRAPPER(RwSettingsUpdated);

void CClientUIInterface::ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style) { return g_ui_signals.ThreadSafeMessageBox(message, caption, style); }
void CClientUIInterface::UpdateMessageBox(const std::string& version, const std::string& message) { return g_ui_signals.UpdateMessageBox(version, message); }
void CClientUIInterface::UpdateMessageBox(const std::string& version, const int& update_type, const std::string& message) { return g_ui_signals.UpdateMessageBox(version, update_type, message); }
bool CClientUIInterface::ThreadSafeAskFee(int64_t nFeeRequired, const std::string& strCaption) { return g_ui_signals.ThreadSafeAskFee(nFeeRequired, strCaption).value_or(false); }
bool CClientUIInterface::ThreadSafeAskQuestion(std::string caption, std::string body) { return g_ui_signals.ThreadSafeAskQuestion(caption, body).value_or(false); }
void CClientUIInterface::ThreadSafeHandleURI(const std::string& strURI) { return g_ui_signals.ThreadSafeHandleURI(strURI); }
Expand Down
2 changes: 1 addition & 1 deletion src/node/ui_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class CClientUIInterface
ADD_SIGNALS_DECL_WRAPPER(ThreadSafeMessageBox, void, const std::string& message, const std::string& caption, int style);

/** Update notification message box. */
ADD_SIGNALS_DECL_WRAPPER(UpdateMessageBox, void, const std::string& version, const std::string& message);
ADD_SIGNALS_DECL_WRAPPER(UpdateMessageBox, void, const std::string& version, const int& update_type, const std::string& message);

/** Ask the user whether they want to pay a fee or not. */
ADD_SIGNALS_DECL_WRAPPER(ThreadSafeAskFee, bool, int64_t nFeeRequired, const std::string& strCaption);
Expand Down
2 changes: 1 addition & 1 deletion src/noui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ static bool noui_ThreadSafeAskFee(int64_t nFeeRequired, const std::string& strCa
return true;
}

static int noui_UpdateMessageBox(const std::string& version, const std::string& message)
static int noui_UpdateMessageBox(const std::string& version, const int& upgrade_type, const std::string& message)
{
std::string caption = _("Gridcoin Update Available");

Expand Down
1 change: 1 addition & 0 deletions src/qt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ add_library(gridcoinqt STATIC
transactionrecord.cpp
transactiontablemodel.cpp
transactionview.cpp
updatedialog.cpp
upgradeqt.cpp
voting/additionalfieldstableview.cpp
voting/additionalfieldstablemodel.cpp
Expand Down
33 changes: 33 additions & 0 deletions src/qt/aboutdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include "qt/decoration.h"
#include "ui_aboutdialog.h"
#include "clientmodel.h"
#include "updatedialog.h"
#include "util.h"

AboutDialog::AboutDialog(QWidget *parent) :
QDialog(parent),
Expand All @@ -11,6 +13,12 @@ AboutDialog::AboutDialog(QWidget *parent) :
ui->copyrightLabel->setText("Copyright 2009-2024 The Bitcoin/Peercoin/Black-Coin/Gridcoin developers");

resize(GRC::ScaleSize(this, width(), height()));

if (!fTestNet) {
connect(ui->versionInfoButton, &QAbstractButton::pressed, this, [this]() { handlePressVersionInfoButton(); });
} else {
ui->versionInfoButton->hide();
}
}

void AboutDialog::setModel(ClientModel *model)
Expand All @@ -30,3 +38,28 @@ void AboutDialog::on_buttonBox_accepted()
{
close();
}

void AboutDialog::handlePressVersionInfoButton()
{
std::string client_message_out;
std::string change_log;
GRC::Upgrade::UpgradeType upgrade_type = GRC::Upgrade::UpgradeType::Unknown;


GRC::Upgrade::CheckForLatestUpdate(client_message_out, change_log, upgrade_type, false, false);

if (client_message_out == std::string {}) {
client_message_out = "No response from GitHub - check network connectivity.";
change_log = " ";
}

UpdateDialog update_dialog;

update_dialog.setWindowTitle("Gridcoin Version Information");
update_dialog.setVersion(QString().fromStdString(client_message_out));
update_dialog.setUpgradeType(static_cast<GRC::Upgrade::UpgradeType>(upgrade_type));
update_dialog.setDetails(QString().fromStdString(change_log));
update_dialog.setModal(false);

update_dialog.exec();
}
1 change: 1 addition & 0 deletions src/qt/aboutdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class AboutDialog : public QDialog

private slots:
void on_buttonBox_accepted();
void handlePressVersionInfoButton();
};

#endif // BITCOIN_QT_ABOUTDIALOG_H
6 changes: 3 additions & 3 deletions src/qt/bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,16 +192,16 @@ static void InitMessage(const std::string &message)
}
}

static void UpdateMessageBox(const std::string& version, const std::string& message)
static void UpdateMessageBox(const std::string& version, const int& update_version, const std::string& message)
{
std::string caption = _("Gridcoin Update Available");

if (guiref)
{
std::string guiaddition = version + _("Click \"Show Details\" to view changes in latest update.");
QMetaObject::invokeMethod(guiref, "update", Qt::QueuedConnection,
Q_ARG(QString, QString::fromStdString(caption)),
Q_ARG(QString, QString::fromStdString(guiaddition)),
Q_ARG(QString, QString::fromStdString(version)),
Q_ARG(int, update_version),
Q_ARG(QString, QString::fromStdString(message)));
}

Expand Down
Loading

0 comments on commit a674f0f

Please sign in to comment.