Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI: Report Game Size On Disk, Make Game Removal An Informed Decision #13088

Merged
merged 1 commit into from Dec 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions rpcs3/Emu/GameInfo.h
Expand Up @@ -20,6 +20,7 @@ struct GameInfo
u32 parental_lvl = 0;
u32 sound_format = 0;
u32 resolution = 0;
usz size_on_disk = umax;

GameInfo()
{
Expand Down
26 changes: 21 additions & 5 deletions rpcs3/rpcs3qt/game_list_frame.cpp
Expand Up @@ -133,6 +133,7 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> gui_settings, std
add_column(gui::column_last_play, tr("Last Played"), tr("Show Last Played"));
add_column(gui::column_playtime, tr("Time Played"), tr("Show Time Played"));
add_column(gui::column_compat, tr("Compatibility"), tr("Show Compatibility"));
add_column(gui::column_dir_size, tr("Space On Disk"), tr("Show Space On Disk"));

// Events
connect(&m_refresh_watcher, &QFutureWatcher<void>::finished, this, &game_list_frame::OnRefreshFinished);
Expand Down Expand Up @@ -608,6 +609,7 @@ void game_list_frame::Refresh(const bool from_drive, const bool scroll_after)
game.sound_format = psf::get_integer(psf, "SOUND_FORMAT", 0);
game.bootable = psf::get_integer(psf, "BOOTABLE", 0);
game.attr = psf::get_integer(psf, "ATTRIBUTE", 0);
game.size_on_disk = fs::get_dir_size(dir);

if (m_show_custom_icons)
{
Expand Down Expand Up @@ -1421,12 +1423,23 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
return;
}

QMessageBox* mb = new QMessageBox(QMessageBox::Question, tr("Confirm %1 Removal").arg(gameinfo->localized_category), tr("Permanently remove %0 from drive?\nPath: %1").arg(name).arg(qstr(current_game.path)), QMessageBox::Yes | QMessageBox::No, this);
mb->setCheckBox(new QCheckBox(tr("Remove caches and custom configs")));
mb->deleteLater();
if (mb->exec() == QMessageBox::Yes)
QString size_information;

if (current_game.size_on_disk != umax)
{
fs::device_stat stat{};
if (fs::statfs(current_game.path, stat))
{
size_information = tr("Game Directory Size: %0\nCurrent Free Disk Space: %1\n\n").arg(gui::utils::format_byte_size(current_game.size_on_disk)).arg(gui::utils::format_byte_size(stat.avail_free));
}
}

QMessageBox mb(QMessageBox::Question, tr("Confirm %1 Removal").arg(gameinfo->localized_category), tr("Permanently remove %0 from drive?\n%1Path: %2").arg(name).arg(size_information).arg(qstr(current_game.path)), QMessageBox::Yes | QMessageBox::No, this);
mb.setCheckBox(new QCheckBox(tr("Remove caches and custom configs")));

if (mb.exec() == QMessageBox::Yes)
{
const bool remove_caches = mb->checkBox()->isChecked();
const bool remove_caches = mb.checkBox()->isChecked();
if (fs::remove_all(current_game.path))
{
if (remove_caches)
Expand Down Expand Up @@ -2579,6 +2592,8 @@ void game_list_frame::PopulateGameList()
}
}

const usz game_size = game->info.size_on_disk;

m_game_list->setItem(row, gui::column_icon, icon_item);
m_game_list->setItem(row, gui::column_name, title_item);
m_game_list->setItem(row, gui::column_serial, serial_item);
Expand All @@ -2593,6 +2608,7 @@ void game_list_frame::PopulateGameList()
m_game_list->setItem(row, gui::column_last_play, new custom_table_widget_item(locale.toString(last_played, last_played >= QDateTime::currentDateTime().addDays(-7) ? gui::persistent::last_played_date_with_time_of_day_format : gui::persistent::last_played_date_format_new), Qt::UserRole, last_played));
m_game_list->setItem(row, gui::column_playtime, new custom_table_widget_item(elapsed_ms == 0 ? tr("Never played") : localized.GetVerboseTimeByMs(elapsed_ms), Qt::UserRole, elapsed_ms));
m_game_list->setItem(row, gui::column_compat, compat_item);
m_game_list->setItem(row, gui::column_dir_size, new custom_table_widget_item(game_size != umax ? gui::utils::format_byte_size(game_size) : tr("Unknown"), Qt::UserRole, QVariant::fromValue<usz>(game_size)));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fromValue because of a compilation issue on GCC/clang.


if (selected_item == game->info.path + game->info.icon_path)
{
Expand Down
13 changes: 6 additions & 7 deletions rpcs3/rpcs3qt/gui_settings.cpp
Expand Up @@ -117,23 +117,22 @@ void gui_settings::ShowBox(QMessageBox::Icon icon, const QString& title, const Q

const QFlags<QMessageBox::StandardButton> buttons = icon != QMessageBox::Information ? QMessageBox::Yes | QMessageBox::No : QMessageBox::Ok;

QMessageBox* mb = new QMessageBox(icon, title, text, buttons, parent, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | (always_on_top ? Qt::WindowStaysOnTopHint : Qt::Widget));
mb->deleteLater();
mb->setTextFormat(Qt::RichText);
QMessageBox mb(icon, title, text, buttons, parent, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | (always_on_top ? Qt::WindowStaysOnTopHint : Qt::Widget));
mb.setTextFormat(Qt::RichText);

if (has_gui_setting && icon != QMessageBox::Critical)
{
mb->setCheckBox(new QCheckBox(tr("Don't show again")));
mb.setCheckBox(new QCheckBox(tr("Don't show again")));
}

connect(mb, &QMessageBox::finished, [&](int res)
connect(&mb, &QMessageBox::finished, [&](int res)
{
if (result)
{
*result = res;
}

const auto checkBox = mb->checkBox();
const auto checkBox = mb.checkBox();

if (checkBox && checkBox->isChecked())
{
Expand All @@ -142,7 +141,7 @@ void gui_settings::ShowBox(QMessageBox::Icon icon, const QString& title, const Q
}
});

mb->exec();
mb.exec();
}

void gui_settings::ShowConfirmationBox(const QString& title, const QString& text, const gui_save& entry, int* result = nullptr, QWidget* parent = nullptr)
Expand Down
3 changes: 3 additions & 0 deletions rpcs3/rpcs3qt/gui_settings.h
Expand Up @@ -33,6 +33,7 @@ namespace gui
column_last_play,
column_playtime,
column_compat,
column_dir_size,

column_count
};
Expand Down Expand Up @@ -69,6 +70,8 @@ namespace gui
return "column_playtime";
case column_compat:
return "column_compat";
case column_dir_size:
return "column_dir_size";
case column_count:
return "";
}
Expand Down
9 changes: 4 additions & 5 deletions rpcs3/rpcs3qt/main_window.cpp
Expand Up @@ -294,13 +294,12 @@ bool main_window::OnMissingFw()
const QString message = tr("Commercial games require the firmware (PS3UPDAT.PUP file) to be installed."
"\n<br>For information about how to obtain the required firmware read the <a href=\"https://rpcs3.net/quickstart\">quickstart guide</a>.");

QMessageBox* mb = new QMessageBox(QMessageBox::Question, title, message, QMessageBox::Ok | QMessageBox::Cancel, this, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowStaysOnTopHint);
mb->deleteLater();
Megamouse marked this conversation as resolved.
Show resolved Hide resolved
mb->setTextFormat(Qt::RichText);
QMessageBox mb(QMessageBox::Question, title, message, QMessageBox::Ok | QMessageBox::Cancel, this, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowStaysOnTopHint);
mb.setTextFormat(Qt::RichText);

mb->button(QMessageBox::Ok)->setText(tr("Locate PS3UPDAT.PUP"));
mb.button(QMessageBox::Ok)->setText(tr("Locate PS3UPDAT.PUP"));

if (mb->exec() == QMessageBox::Ok)
if (mb.exec() == QMessageBox::Ok)
{
InstallPup();
return true;
Expand Down
16 changes: 16 additions & 0 deletions rpcs3/rpcs3qt/qt_utils.cpp
Expand Up @@ -589,5 +589,21 @@ namespace gui
}
}
}

QString format_byte_size(usz size)
{
usz byte_unit = 0;
usz divisor = 1;

static const QString s_units[]{"B", "KB", "MB", "GB", "TB", "PB"};

while (byte_unit < std::size(s_units) - 1 && size / divisor >= 1024)
{
byte_unit++;
divisor *= 1024;
}

return QStringLiteral("%0 %1").arg(QString::number((size + 0.) / divisor, 'f', 2)).arg(s_units[byte_unit]);
}
} // utils
} // gui
3 changes: 3 additions & 0 deletions rpcs3/rpcs3qt/qt_utils.h
Expand Up @@ -124,5 +124,8 @@ namespace gui

// Sort a QTreeWidget (currently only column 0)
void sort_tree(QTreeWidget* tree, Qt::SortOrder sort_order, bool recursive);

// Convert an arbitrary count of bytes to a readable format using global units (KB, MB...)
QString format_byte_size(usz size);
} // utils
} // gui