Merge branch 'master' into master

This commit is contained in:
Ani 2025-12-02 19:45:14 +00:00 committed by GitHub
commit a321c898f0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 140 additions and 98 deletions

View file

@ -230,36 +230,28 @@ bool main_window::Init([[maybe_unused]] bool with_cli_boot)
// RPCS3 Updater // RPCS3 Updater
QMenu* download_menu = new QMenu(tr("Update Available!")); connect(ui->actionDownload_Update, &QAction::triggered, this, [this]
QAction* download_action = new QAction(tr("Download Update"), download_menu);
connect(download_action, &QAction::triggered, this, [this]
{ {
m_updater.update(false); m_updater.update(false);
}); });
download_menu->addAction(download_action);
#ifdef _WIN32 #ifdef _WIN32
// Use a menu at the top right corner to indicate the new version. // Use a menu at the top right corner to indicate the new version.
// Some distros just can't handle corner widgets at the moment.
QMenuBar* corner_bar = new QMenuBar(ui->menuBar); QMenuBar* corner_bar = new QMenuBar(ui->menuBar);
m_download_menu_action = corner_bar->addMenu(download_menu); corner_bar->addMenu(ui->menuUpdate_Available);
ui->menuBar->setCornerWidget(corner_bar); ui->menuBar->setCornerWidget(corner_bar);
ui->menuBar->cornerWidget()->setVisible(false); ui->menuBar->cornerWidget()->setVisible(false);
#else ui->menuBar->removeAction(ui->menuUpdate_Available->menuAction());
// Append a menu to the right of the regular menus to indicate the new version.
// Some distros just can't handle corner widgets at the moment.
m_download_menu_action = ui->menuBar->addMenu(download_menu);
#endif #endif
ensure(m_download_menu_action); ui->menuUpdate_Available->setVisible(false);
m_download_menu_action->setVisible(false);
connect(&m_updater, &update_manager::signal_update_available, this, [this](bool update_available) connect(&m_updater, &update_manager::signal_update_available, this, [this](bool update_available)
{ {
if (m_download_menu_action) if (ui->menuUpdate_Available)
{ {
m_download_menu_action->setVisible(update_available); ui->menuUpdate_Available->setVisible(update_available);
} }
if (ui->menuBar && ui->menuBar->cornerWidget()) if (ui->menuBar && ui->menuBar->cornerWidget())
{ {
@ -1933,9 +1925,11 @@ void main_window::OnEmuRun(bool /*start_playtime*/)
EnableMenus(true); EnableMenus(true);
update_gui_pad_thread(); update_gui_pad_thread();
m_system_state = system_state::running;
} }
void main_window::OnEmuResume() const void main_window::OnEmuResume()
{ {
const QString title = GetCurrentTitle(); const QString title = GetCurrentTitle();
const QString restart_tooltip = tr("Restart %0").arg(title); const QString restart_tooltip = tr("Restart %0").arg(title);
@ -1948,9 +1942,11 @@ void main_window::OnEmuResume() const
ui->toolbar_start->setText(tr("Pause")); ui->toolbar_start->setText(tr("Pause"));
ui->toolbar_start->setToolTip(pause_tooltip); ui->toolbar_start->setToolTip(pause_tooltip);
ui->toolbar_stop->setToolTip(stop_tooltip); ui->toolbar_stop->setToolTip(stop_tooltip);
m_system_state = system_state::starting; // Let's just use this state to distinguish between resumed and running
} }
void main_window::OnEmuPause() const void main_window::OnEmuPause()
{ {
const QString title = GetCurrentTitle(); const QString title = GetCurrentTitle();
const QString resume_tooltip = tr("Resume %0").arg(title); const QString resume_tooltip = tr("Resume %0").arg(title);
@ -1966,6 +1962,8 @@ void main_window::OnEmuPause() const
{ {
m_game_list_frame->Refresh(); m_game_list_frame->Refresh();
} }
m_system_state = system_state::paused;
} }
void main_window::OnEmuStop() void main_window::OnEmuStop()
@ -2026,9 +2024,11 @@ void main_window::OnEmuStop()
} }
update_gui_pad_thread(); update_gui_pad_thread();
m_system_state = system_state::stopped;
} }
void main_window::OnEmuReady() const void main_window::OnEmuReady()
{ {
const QString title = GetCurrentTitle(); const QString title = GetCurrentTitle();
const QString play_tooltip = tr("Play %0").arg(title); const QString play_tooltip = tr("Play %0").arg(title);
@ -2054,6 +2054,8 @@ void main_window::OnEmuReady() const
ui->removeAllCachesAct->setEnabled(false); ui->removeAllCachesAct->setEnabled(false);
ui->removeSavestatesAct->setEnabled(false); ui->removeSavestatesAct->setEnabled(false);
ui->cleanUpGameListAct->setEnabled(false); ui->cleanUpGameListAct->setEnabled(false);
m_system_state = system_state::ready;
} }
void main_window::EnableMenus(bool enabled) const void main_window::EnableMenus(bool enabled) const
@ -2340,6 +2342,20 @@ void main_window::RetranslateUI(const QStringList& language_codes, const QString
ui->retranslateUi(this); ui->retranslateUi(this);
// Update menu bar size (needed if the corner widget changes its size)
ui->menuBar->adjustSize();
// Update toolbar elements
switch (m_system_state)
{
case system_state::running: OnEmuRun(false); break;
case system_state::stopped: OnEmuStop(); break;
case system_state::paused: OnEmuPause(); break;
case system_state::starting: OnEmuResume(); break;
case system_state::ready: OnEmuReady(); break;
default: break;
}
if (m_game_list_frame) if (m_game_list_frame)
{ {
m_game_list_frame->Refresh(true); m_game_list_frame->Refresh(true);

View file

@ -11,6 +11,7 @@
#include "settings.h" #include "settings.h"
#include "shortcut_handler.h" #include "shortcut_handler.h"
#include "Emu/config_mode.h" #include "Emu/config_mode.h"
#include "Emu/System.h"
#include <memory> #include <memory>
@ -88,9 +89,9 @@ Q_SIGNALS:
public Q_SLOTS: public Q_SLOTS:
void OnEmuStop(); void OnEmuStop();
void OnEmuRun(bool start_playtime); void OnEmuRun(bool start_playtime);
void OnEmuResume() const; void OnEmuResume();
void OnEmuPause() const; void OnEmuPause();
void OnEmuReady() const; void OnEmuReady();
void OnEnableDiscEject(bool enabled) const; void OnEnableDiscEject(bool enabled) const;
void OnEnableDiscInsert(bool enabled) const; void OnEnableDiscInsert(bool enabled) const;
void OnAddBreakpoint(u32 addr) const; void OnAddBreakpoint(u32 addr) const;
@ -196,9 +197,10 @@ private:
std::shared_ptr<persistent_settings> m_persistent_settings; std::shared_ptr<persistent_settings> m_persistent_settings;
update_manager m_updater; update_manager m_updater;
QAction* m_download_menu_action = nullptr;
shortcut_handler* m_shortcut_handler = nullptr; shortcut_handler* m_shortcut_handler = nullptr;
std::unique_ptr<gui_pad_thread> m_gui_pad_thread; std::unique_ptr<gui_pad_thread> m_gui_pad_thread;
system_state m_system_state = system_state::stopped;
}; };

View file

@ -412,6 +412,12 @@
<addaction name="aboutAct"/> <addaction name="aboutAct"/>
<addaction name="aboutQtAct"/> <addaction name="aboutQtAct"/>
</widget> </widget>
<widget class="QMenu" name="menuUpdate_Available">
<property name="title">
<string>Update Available!</string>
</property>
<addaction name="actionDownload_Update"/>
</widget>
<addaction name="menuFile"/> <addaction name="menuFile"/>
<addaction name="menuEmulation"/> <addaction name="menuEmulation"/>
<addaction name="menuConfiguration"/> <addaction name="menuConfiguration"/>
@ -419,6 +425,7 @@
<addaction name="menuUtilities"/> <addaction name="menuUtilities"/>
<addaction name="menuView"/> <addaction name="menuView"/>
<addaction name="menuHelp"/> <addaction name="menuHelp"/>
<addaction name="menuUpdate_Available"/>
</widget> </widget>
<widget class="QToolBar" name="toolBar"> <widget class="QToolBar" name="toolBar">
<property name="sizePolicy"> <property name="sizePolicy">
@ -1448,6 +1455,11 @@
<string>Sound Effects</string> <string>Sound Effects</string>
</property> </property>
</action> </action>
<action name="actionDownload_Update">
<property name="text">
<string>Download Update</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<resources> <resources>

View file

@ -3,12 +3,15 @@
movie_item::movie_item() : QTableWidgetItem(), movie_item_base() movie_item::movie_item() : QTableWidgetItem(), movie_item_base()
{ {
setData(Qt::UserRole, {}); // Set any value to UserRole for proper indexing (e.g. for multiselection)
} }
movie_item::movie_item(const QString& text, int type) : QTableWidgetItem(text, type), movie_item_base() movie_item::movie_item(const QString& text, int type) : QTableWidgetItem(text, type), movie_item_base()
{ {
setData(Qt::UserRole, {}); // Set any value to UserRole for proper indexing (e.g. for multiselection)
} }
movie_item::movie_item(const QIcon& icon, const QString& text, int type) : QTableWidgetItem(icon, text, type), movie_item_base() movie_item::movie_item(const QIcon& icon, const QString& text, int type) : QTableWidgetItem(icon, text, type), movie_item_base()
{ {
setData(Qt::UserRole, {}); // Set any value to UserRole for proper indexing (e.g. for multiselection)
} }

View file

@ -85,6 +85,7 @@ savestate_manager_dialog::savestate_manager_dialog(std::shared_ptr<gui_settings>
m_savestate_table->horizontalScrollBar()->setSingleStep(20); m_savestate_table->horizontalScrollBar()->setSingleStep(20);
m_savestate_table->setItemDelegate(new table_item_delegate(m_savestate_table, false)); m_savestate_table->setItemDelegate(new table_item_delegate(m_savestate_table, false));
m_savestate_table->setSelectionBehavior(QAbstractItemView::SelectRows); m_savestate_table->setSelectionBehavior(QAbstractItemView::SelectRows);
m_savestate_table->setSelectionMode(QAbstractItemView::SingleSelection);
m_savestate_table->setEditTriggers(QAbstractItemView::NoEditTriggers); m_savestate_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_savestate_table->setColumnCount(static_cast<int>(gui::savestate_list_columns::count)); m_savestate_table->setColumnCount(static_cast<int>(gui::savestate_list_columns::count));
m_savestate_table->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); m_savestate_table->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);

View file

@ -56,8 +56,7 @@ void update_manager::check_for_updates(bool automatic, bool check_only, bool aut
{ {
update_log.notice("Checking for updates: automatic=%d, check_only=%d, auto_accept=%d", automatic, check_only, auto_accept); update_log.notice("Checking for updates: automatic=%d, check_only=%d, auto_accept=%d", automatic, check_only, auto_accept);
m_update_message.clear(); m_update_info = {};
m_changelog.clear();
if (automatic) if (automatic)
{ {
@ -103,7 +102,7 @@ void update_manager::check_for_updates(bool automatic, bool check_only, bool aut
} }
} }
Q_EMIT signal_update_available(result_json && !m_update_message.isEmpty()); Q_EMIT signal_update_available(result_json && m_update_info.update_found);
}); });
const utils::OS_version os = utils::get_OS_version(); const utils::OS_version os = utils::get_OS_version();
@ -121,7 +120,7 @@ bool update_manager::handle_json(bool automatic, bool check_only, bool auto_acce
const QJsonObject json_data = QJsonDocument::fromJson(data).object(); const QJsonObject json_data = QJsonDocument::fromJson(data).object();
const int return_code = json_data["return_code"].toInt(-255); const int return_code = json_data["return_code"].toInt(-255);
bool hash_found = true; m_update_info.hash_found = true;
if (return_code < 0) if (return_code < 0)
{ {
@ -143,7 +142,7 @@ bool update_manager::handle_json(bool automatic, bool check_only, bool auto_acce
// If a user clicks "Check for Updates" with a custom build ask him if he's sure he wants to update to latest version // If a user clicks "Check for Updates" with a custom build ask him if he's sure he wants to update to latest version
if (!automatic && return_code == -1) if (!automatic && return_code == -1)
{ {
hash_found = false; m_update_info.hash_found = false;
} }
else else
{ {
@ -187,7 +186,7 @@ bool update_manager::handle_json(bool automatic, bool check_only, bool auto_acce
check_json(latest["version"].isString(), "Node 'latest_build: version' not found or not a string") && check_json(latest["version"].isString(), "Node 'latest_build: version' not found or not a string") &&
check_json(latest["datetime"].isString(), "Node 'latest_build: datetime' not found or not a string") check_json(latest["datetime"].isString(), "Node 'latest_build: datetime' not found or not a string")
) || ) ||
(hash_found && !( (m_update_info.hash_found && !(
check_json(current.isObject(), "JSON doesn't contain current_build section") && check_json(current.isObject(), "JSON doesn't contain current_build section") &&
check_json(current["version"].isString(), "Node 'current_build: datetime' not found or not a string") && check_json(current["version"].isString(), "Node 'current_build: datetime' not found or not a string") &&
check_json(current["datetime"].isString(), "Node 'current_build: version' not found or not a string") check_json(current["datetime"].isString(), "Node 'current_build: version' not found or not a string")
@ -196,7 +195,7 @@ bool update_manager::handle_json(bool automatic, bool check_only, bool auto_acce
return false; return false;
} }
if (hash_found && return_code == 0) if (m_update_info.hash_found && return_code == 0)
{ {
update_log.success("RPCS3 is up to date!"); update_log.success("RPCS3 is up to date!");
m_downloader->close_progress_dialog(); m_downloader->close_progress_dialog();
@ -210,58 +209,25 @@ bool update_manager::handle_json(bool automatic, bool check_only, bool auto_acce
// Calculate how old the build is // Calculate how old the build is
const QString date_fmt = QStringLiteral("yyyy-MM-dd hh:mm:ss"); const QString date_fmt = QStringLiteral("yyyy-MM-dd hh:mm:ss");
const QDateTime cur_date = hash_found ? QDateTime::fromString(current["datetime"].toString(), date_fmt) : QDateTime::currentDateTimeUtc(); const QDateTime cur_date = m_update_info.hash_found ? QDateTime::fromString(current["datetime"].toString(), date_fmt) : QDateTime::currentDateTimeUtc();
const QDateTime lts_date = QDateTime::fromString(latest["datetime"].toString(), date_fmt); const QDateTime lts_date = QDateTime::fromString(latest["datetime"].toString(), date_fmt);
const QString cur_str = cur_date.toString(date_fmt); m_update_info.update_found = true;
const QString lts_str = lts_date.toString(date_fmt); m_update_info.cur_date = cur_date.toString(date_fmt);
m_update_info.lts_date = lts_date.toString(date_fmt);
m_update_info.diff_msec = cur_date.msecsTo(lts_date);
m_update_info.new_version = latest["version"].toString();
const qint64 diff_msec = cur_date.msecsTo(lts_date); if (m_update_info.hash_found)
update_log.notice("Current: %s, latest: %s, difference: %lld ms", cur_str, lts_str, diff_msec);
const Localized localized;
const QString new_version = latest["version"].toString();
m_new_version = new_version.toStdString();
const QString support_message = tr("<br>You can empower our project at <a href=\"https://rpcs3.net/patreon\">RPCS3 Patreon</a>.<br>");
if (hash_found)
{ {
const QString old_version = current["version"].toString(); m_update_info.old_version = current["version"].toString();
m_old_version = old_version.toStdString();
if (diff_msec < 0)
{
// This usually means that the current version was marked as broken and won't be shipped anymore, so we need to downgrade to avoid certain bugs.
m_update_message = tr("A better version of RPCS3 is available!<br><br>Current version: %0 (%1)<br>Better version: %2 (%3)<br>%4<br>Do you want to update?")
.arg(old_version)
.arg(cur_str)
.arg(new_version)
.arg(lts_str)
.arg(support_message);
} }
else else
{ {
m_update_message = tr("A new version of RPCS3 is available!<br><br>Current version: %0 (%1)<br>Latest version: %2 (%3)<br>Your version is %4 behind.<br>%5<br>Do you want to update?") m_update_info.old_version = QString::fromStdString(fmt::format("%s-%s-%s", rpcs3::get_full_branch(), rpcs3::get_branch(), rpcs3::get_version().to_string()));
.arg(old_version)
.arg(cur_str)
.arg(new_version)
.arg(lts_str)
.arg(localized.GetVerboseTimeByMs(diff_msec, true))
.arg(support_message);
} }
}
else
{
m_old_version = fmt::format("%s-%s-%s", rpcs3::get_full_branch(), rpcs3::get_branch(), rpcs3::get_version().to_string());
m_update_message = tr("You're currently using a custom or PR build.<br><br>Latest version: %0 (%1)<br>The latest version is %2 old.<br>%3<br>Do you want to update to the latest official RPCS3 version?") update_log.notice("Current: %s, latest: %s, difference: %lld ms", m_update_info.cur_date, m_update_info.lts_date, m_update_info.diff_msec);
.arg(new_version)
.arg(lts_str)
.arg(localized.GetVerboseTimeByMs(std::abs(diff_msec), true))
.arg(support_message);
}
m_request_url = latest[os]["download"].toString().toStdString(); m_request_url = latest[os]["download"].toString().toStdString();
m_expected_hash = latest[os]["checksum"].toString().toStdString(); m_expected_hash = latest[os]["checksum"].toString().toStdString();
@ -277,9 +243,9 @@ bool update_manager::handle_json(bool automatic, bool check_only, bool auto_acce
if (!auto_accept) if (!auto_accept)
{ {
if (automatic && m_gui_settings->GetValue(gui::ib_skip_version).toString() == new_version) if (automatic && m_gui_settings->GetValue(gui::ib_skip_version).toString() == m_update_info.new_version)
{ {
update_log.notice("Skipping automatic update notification for version '%s' due to user preference", new_version); update_log.notice("Skipping automatic update notification for version '%s' due to user preference", m_update_info.new_version);
m_downloader->close_progress_dialog(); m_downloader->close_progress_dialog();
return true; return true;
} }
@ -300,7 +266,6 @@ bool update_manager::handle_json(bool automatic, bool check_only, bool auto_acce
} }
else else
{ {
entry.version = tr("N/A");
update_log.notice("JSON changelog entry does not contain a version string."); update_log.notice("JSON changelog entry does not contain a version string.");
} }
@ -310,11 +275,10 @@ bool update_manager::handle_json(bool automatic, bool check_only, bool auto_acce
} }
else else
{ {
entry.title = tr("N/A");
update_log.notice("JSON changelog entry does not contain a title string."); update_log.notice("JSON changelog entry does not contain a title string.");
} }
m_changelog.push_back(entry); m_update_info.changelog.push_back(std::move(entry));
} }
else else
{ {
@ -351,25 +315,61 @@ void update_manager::update(bool auto_accept)
if (!auto_accept) if (!auto_accept)
{ {
if (m_update_message.isEmpty()) if (!m_update_info.update_found)
{ {
// This can happen if we abort the check_for_updates download. Just check again in this case. // This can happen if we abort the check_for_updates download. Just check again in this case.
update_log.notice("Aborting update: Update message is empty. Trying again..."); update_log.notice("Aborting update: Update not found. Trying again...");
m_downloader->close_progress_dialog(); m_downloader->close_progress_dialog();
check_for_updates(false, false, false, m_parent); check_for_updates(false, false, false, m_parent);
return; return;
} }
const Localized localized;
const QString support_message = tr("<br>You can empower our project at <a href=\"https://rpcs3.net/patreon\">RPCS3 Patreon</a>.<br>");
QString update_message;
if (m_update_info.hash_found)
{
if (m_update_info.diff_msec < 0)
{
// This usually means that the current version was marked as broken and won't be shipped anymore, so we need to downgrade to avoid certain bugs.
update_message = tr("A better version of RPCS3 is available!<br><br>Current version: %0 (%1)<br>Better version: %2 (%3)<br>%4<br>Do you want to update?")
.arg(m_update_info.old_version)
.arg(m_update_info.cur_date)
.arg(m_update_info.new_version)
.arg(m_update_info.lts_date)
.arg(support_message);
}
else
{
update_message = tr("A new version of RPCS3 is available!<br><br>Current version: %0 (%1)<br>Latest version: %2 (%3)<br>Your version is %4 behind.<br>%5<br>Do you want to update?")
.arg(m_update_info.old_version)
.arg(m_update_info.cur_date)
.arg(m_update_info.new_version)
.arg(m_update_info.lts_date)
.arg(localized.GetVerboseTimeByMs(m_update_info.diff_msec, true))
.arg(support_message);
}
}
else
{
update_message = tr("You're currently using a custom or PR build.<br><br>Latest version: %0 (%1)<br>The latest version is %2 old.<br>%3<br>Do you want to update to the latest official RPCS3 version?")
.arg(m_update_info.new_version)
.arg(m_update_info.lts_date)
.arg(localized.GetVerboseTimeByMs(std::abs(m_update_info.diff_msec), true))
.arg(support_message);
}
QString changelog_content; QString changelog_content;
for (const changelog_data& entry : m_changelog) for (const changelog_data& entry : m_update_info.changelog)
{ {
if (!changelog_content.isEmpty()) if (!changelog_content.isEmpty())
changelog_content.append('\n'); changelog_content.append('\n');
changelog_content.append(tr("• %0: %1").arg(entry.version, entry.title)); changelog_content.append(tr("• %0: %1").arg(entry.version.isEmpty() ? tr("N/A") : entry.version, entry.title.isEmpty() ? tr("N/A") : entry.title));
} }
QMessageBox mb(QMessageBox::Icon::Question, tr("Update Available"), m_update_message, QMessageBox::Yes | QMessageBox::No, m_downloader->get_progress_dialog() ? m_downloader->get_progress_dialog() : m_parent); QMessageBox mb(QMessageBox::Icon::Question, tr("Update Available"), update_message, QMessageBox::Yes | QMessageBox::No, m_downloader->get_progress_dialog() ? m_downloader->get_progress_dialog() : m_parent);
mb.setTextFormat(Qt::RichText); mb.setTextFormat(Qt::RichText);
mb.setCheckBox(new QCheckBox(tr("Don't show again for this version"))); mb.setCheckBox(new QCheckBox(tr("Don't show again for this version")));
@ -380,16 +380,16 @@ void update_manager::update(bool auto_accept)
// Smartass hack to make the unresizeable message box wide enough for the changelog // Smartass hack to make the unresizeable message box wide enough for the changelog
const int changelog_width = QLabel(changelog_content).sizeHint().width(); const int changelog_width = QLabel(changelog_content).sizeHint().width();
if (QLabel(m_update_message).sizeHint().width() < changelog_width) if (QLabel(update_message).sizeHint().width() < changelog_width)
{ {
m_update_message += " &nbsp;"; update_message += " &nbsp;";
while (QLabel(m_update_message).sizeHint().width() < changelog_width) while (QLabel(update_message).sizeHint().width() < changelog_width)
{ {
m_update_message += "&nbsp;"; update_message += "&nbsp;";
} }
} }
mb.setText(m_update_message); mb.setText(update_message);
} }
update_log.notice("Asking user for permission to update..."); update_log.notice("Asking user for permission to update...");
@ -400,8 +400,8 @@ void update_manager::update(bool auto_accept)
if (mb.checkBox()->isChecked()) if (mb.checkBox()->isChecked())
{ {
update_log.notice("User requested to skip further automatic update notifications for version '%s'", m_new_version); update_log.notice("User requested to skip further automatic update notifications for version '%s'", m_update_info.new_version);
m_gui_settings->SetValue(gui::ib_skip_version, QString::fromStdString(m_new_version)); m_gui_settings->SetValue(gui::ib_skip_version, m_update_info.new_version);
} }
m_downloader->close_progress_dialog(); m_downloader->close_progress_dialog();
@ -751,7 +751,7 @@ bool update_manager::handle_rpcs3(const QByteArray& data, bool auto_accept)
if (fs::file update_file{fs::get_config_dir() + "update_history.log", fs::create + fs::write + fs::append}) if (fs::file update_file{fs::get_config_dir() + "update_history.log", fs::create + fs::write + fs::append})
{ {
const std::string update_time = QDateTime::currentDateTime().toString("yyyy/MM/dd hh:mm:ss").toStdString(); const std::string update_time = QDateTime::currentDateTime().toString("yyyy/MM/dd hh:mm:ss").toStdString();
const std::string entry = fmt::format("%s: Updated from \"%s\" to \"%s\"", update_time, m_old_version, m_new_version); const std::string entry = fmt::format("%s: Updated from \"%s\" to \"%s\"", update_time, m_update_info.old_version, m_update_info.new_version);
update_file.write(fmt::format("%s\n", entry)); update_file.write(fmt::format("%s\n", entry));
update_log.notice("Added entry '%s' to update_history.log", entry); update_log.notice("Added entry '%s' to update_history.log", entry);
} }

View file

@ -19,20 +19,28 @@ private:
std::shared_ptr<gui_settings> m_gui_settings; std::shared_ptr<gui_settings> m_gui_settings;
// This message is empty if there is no download available
QString m_update_message;
struct changelog_data struct changelog_data
{ {
QString version; QString version;
QString title; QString title;
}; };
std::vector<changelog_data> m_changelog;
struct update_info
{
bool update_found = false;
bool hash_found = false;
qint64 diff_msec = 0;
QString cur_date;
QString lts_date;
QString old_version;
QString new_version;
std::vector<changelog_data> changelog;
};
update_info m_update_info {};
std::string m_request_url; std::string m_request_url;
std::string m_expected_hash; std::string m_expected_hash;
std::string m_old_version;
std::string m_new_version;
u64 m_expected_size = 0; u64 m_expected_size = 0;
bool handle_json(bool automatic, bool check_only, bool auto_accept, const QByteArray& data); bool handle_json(bool automatic, bool check_only, bool auto_accept, const QByteArray& data);