Qt: Add confirmation dialogs before closing games

This commit is contained in:
Megamouse 2020-04-22 13:08:16 +02:00
parent ebd92a2f2f
commit 2b6afb6916
8 changed files with 139 additions and 72 deletions

View File

@ -2265,6 +2265,7 @@
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
<ClInclude Include="rpcs3qt\gui_save.h" />
<ClInclude Include="rpcs3qt\stylesheets.h" />
<CustomBuild Include="rpcs3qt\skylander_dialog.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>

View File

@ -1137,6 +1137,9 @@
<ClInclude Include="rpcs3qt\config_adapter.h">
<Filter>Gui\settings</Filter>
</ClInclude>
<ClInclude Include="rpcs3qt\gui_save.h">
<Filter>Gui\settings</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="debug\moc_predefs.h.cbt">

View File

@ -817,6 +817,36 @@ void game_list_frame::itemSelectionChangedSlot()
Q_EMIT NotifyGameSelection(game);
}
bool game_list_frame::GetBootConfirmation(const gui_save& gui_save_entry)
{
if (m_gui_settings && !Emu.IsStopped())
{
QString title = tr("Close Running Game?");
QString message = tr("Performing this action will close the current game.\nDo you really want to continue?\n\nAny unsaved progress will be lost!\n");
if (gui_save_entry == gui::ib_confirm_boot)
{
message = tr("Booting another game will close the current game.\nDo you really want to boot another game?\n\nAny unsaved progress will be lost!\n");
}
else if (gui_save_entry == gui::ib_confirm_exit)
{
title = tr("Exit RPCS3?");
message = tr("A game is currently running. Do you really want to close RPCS3?\n\nAny unsaved progress will be lost!\n");
}
int result = QMessageBox::Yes;
m_gui_settings->ShowConfirmationBox(title, message, gui_save_entry, &result, this);
if (result != QMessageBox::Yes)
{
return false;
}
}
return true;
}
void game_list_frame::ShowContextMenu(const QPoint &pos)
{
QPoint global_pos;
@ -1029,7 +1059,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
Emu.GetCallbacks().enable_pads(true);
}
});
connect(hide_serial, &QAction::triggered, [=, this](bool checked)
connect(hide_serial, &QAction::triggered, [serial, this](bool checked)
{
if (checked)
m_hidden_list.insert(serial);
@ -1039,9 +1069,12 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
m_gui_settings->SetValue(gui::gl_hidden_list, QStringList(m_hidden_list.values()));
Refresh();
});
connect(create_ppu_cache, &QAction::triggered, [=, this]
connect(create_ppu_cache, &QAction::triggered, [gameinfo, this]
{
CreatePPUCache(gameinfo);
if (GetBootConfirmation())
{
CreatePPUCache(gameinfo);
}
});
connect(remove_game, &QAction::triggered, [=, this]
{
@ -1398,6 +1431,11 @@ void game_list_frame::BatchCreatePPUCaches()
return;
}
if (!GetBootConfirmation())
{
return;
}
progress_dialog* pdlg = new progress_dialog(tr("PPU Cache Batch Creation"), tr("Creating all PPU caches"), tr("Cancel"), 0, total, true, this);
pdlg->setAutoClose(false);
pdlg->setAutoReset(false);

View File

@ -4,6 +4,7 @@
#include "custom_dock_widget.h"
#include "game_compatibility.h"
#include "gui_save.h"
#include <QMainWindow>
#include <QToolBar>
@ -68,6 +69,8 @@ public:
void SetShowHidden(bool show);
bool GetBootConfirmation(const gui_save& gui_save_entry = gui_save());
public Q_SLOTS:
void BatchCreatePPUCaches();
void BatchRemovePPUCaches();

30
rpcs3/rpcs3qt/gui_save.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#include <QString>
#include <QVariant>
struct gui_save
{
QString key;
QString name;
QVariant def;
gui_save()
{
key = "";
name = "";
def = QVariant();
}
gui_save(const QString& k, const QString& n, const QVariant& d)
{
key = k;
name = n;
def = d;
}
bool operator==(const gui_save& rhs) const noexcept
{
return key == rhs.key && name == rhs.name && def == rhs.def;
}
};

View File

@ -172,36 +172,39 @@ void gui_settings::SetCategoryVisibility(int cat, const bool& val)
void gui_settings::ShowBox(bool confirm, const QString& title, const QString& text, const gui_save& entry, int* result = nullptr, QWidget* parent = nullptr, bool always_on_top = false)
{
const std::string dialog_type = confirm ? "Confirmation" : "Info";
const bool has_gui_setting = !entry.name.isEmpty();
if (entry.name.isEmpty() || GetValue(entry).toBool())
if (has_gui_setting && !GetValue(entry).toBool())
{
const QFlags<QMessageBox::StandardButton> buttons = confirm ? QMessageBox::Yes | QMessageBox::No : QMessageBox::Ok;
const QMessageBox::Icon icon = confirm ? QMessageBox::Question : QMessageBox::Information;
QMessageBox* mb = new QMessageBox(icon, title, text, buttons, parent, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | (always_on_top ? Qt::WindowStaysOnTopHint : Qt::Widget));
mb->deleteLater();
if (!entry.name.isEmpty())
{
mb->setCheckBox(new QCheckBox(tr("Don't show again")));
}
connect(mb, &QMessageBox::finished, [&](int res)
{
if (result)
{
*result = res;
}
if (!entry.name.isEmpty() && mb->checkBox()->isChecked())
{
SetValue(entry, false);
cfg_log.notice("%s Dialog for Entry %s is now disabled", dialog_type, sstr(entry.name));
}
});
mb->exec();
cfg_log.notice("%s Dialog for Entry %s was ignored", dialog_type, sstr(entry.name));
return;
}
else cfg_log.notice("%s Dialog for Entry %s was ignored", dialog_type, sstr(entry.name));
const QFlags<QMessageBox::StandardButton> buttons = confirm ? QMessageBox::Yes | QMessageBox::No : QMessageBox::Ok;
const QMessageBox::Icon icon = confirm ? QMessageBox::Question : QMessageBox::Information;
QMessageBox* mb = new QMessageBox(icon, title, text, buttons, parent, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | (always_on_top ? Qt::WindowStaysOnTopHint : Qt::Widget));
mb->deleteLater();
if (has_gui_setting)
{
mb->setCheckBox(new QCheckBox(tr("Don't show again")));
}
connect(mb, &QMessageBox::finished, [&](int res)
{
if (result)
{
*result = res;
}
if (has_gui_setting && mb->checkBox()->isChecked())
{
SetValue(entry, false);
cfg_log.notice("%s Dialog for Entry %s is now disabled", dialog_type, sstr(entry.name));
}
});
mb->exec();
}
void gui_settings::ShowConfirmationBox(const QString& title, const QString& text, const gui_save& entry, int* result = nullptr, QWidget* parent = nullptr)

View File

@ -300,17 +300,9 @@ void main_window::show_boot_error(game_boot_result status)
void main_window::Boot(const std::string& path, const std::string& title_id, bool direct, bool add_only, bool force_global_config)
{
if (!Emu.IsStopped())
if (!m_game_list_frame->GetBootConfirmation(gui::ib_confirm_boot))
{
int result = QMessageBox::Yes;
m_gui_settings->ShowConfirmationBox(tr("Close Running Game?"),
tr("Booting another game will close the current game.\nDo you really want to boot another game?\n\nAny unsaved progress will be lost!\n"),
gui::ib_confirm_boot, &result, this);
if (result != QMessageBox::Yes)
{
return;
}
return;
}
m_app_icon = gui::utils::get_app_icon_from_path(path, title_id);
@ -427,6 +419,11 @@ void main_window::BootRsxCapture(std::string path)
path = sstr(file_path);
}
if (!m_game_list_frame->GetBootConfirmation())
{
return;
}
Emu.SetForceBoot(true);
Emu.Stop();
@ -479,6 +476,11 @@ void main_window::HandlePackageInstallation(QStringList file_paths)
return;
}
if (!m_game_list_frame->GetBootConfirmation())
{
return;
}
progress_dialog pdlg(tr("RPCS3 Package Installer"), tr("Installing package, please wait..."), tr("Cancel"), 0, 1000, false, this);
pdlg.show();
@ -601,6 +603,11 @@ void main_window::HandlePupInstallation(QString file_path)
return;
}
if (!m_game_list_frame->GetBootConfirmation())
{
return;
}
Emu.SetForceBoot(true);
Emu.Stop();
@ -757,6 +764,11 @@ void main_window::DecryptSPRXLibraries()
{
return;
}
if (!m_game_list_frame->GetBootConfirmation())
{
return;
}
Emu.SetForceBoot(true);
Emu.Stop();
@ -2037,6 +2049,11 @@ void main_window::RemoveFirmwareCache()
void main_window::CreateFirmwareCache()
{
if (!m_game_list_frame->GetBootConfirmation())
{
return;
}
Emu.SetForceBoot(true);
Emu.BootGame(g_cfg.vfs.get_dev_flash() + "sys/external/", "", true);
}
@ -2076,19 +2093,10 @@ void main_window::mouseDoubleClickEvent(QMouseEvent *event)
*/
void main_window::closeEvent(QCloseEvent* closeEvent)
{
if (!Emu.IsStopped() && m_gui_settings->GetValue(gui::ib_confirm_exit).toBool())
if (!m_game_list_frame->GetBootConfirmation(gui::ib_confirm_exit))
{
int result = QMessageBox::Yes;
m_gui_settings->ShowConfirmationBox(tr("Exit RPCS3?"),
tr("A game is currently running. Do you really want to close RPCS3?\n\nAny unsaved progress will be lost!\n"),
gui::ib_confirm_exit, &result, nullptr);
if (result != QMessageBox::Yes)
{
closeEvent->ignore();
return;
}
closeEvent->ignore();
return;
}
// Cleanly stop the emulator.

View File

@ -7,26 +7,7 @@
#include <memory>
struct gui_save
{
QString key;
QString name;
QVariant def;
gui_save()
{
key = "";
name = "";
def = QVariant();
}
gui_save(const QString& k, const QString& n, const QVariant& d)
{
key = k;
name = n;
def = d;
}
};
#include "gui_save.h"
typedef QPair<QString, QString> q_string_pair;
typedef QPair<QString, QSize> q_size_pair;