Merge pull request #2503 from lioncash/util
yuzu/game_list: Specify string conversions explicitly
This commit is contained in:
commit
dbcff5d574
7 changed files with 92 additions and 84 deletions
|
@ -188,7 +188,9 @@ private:
|
||||||
GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread)
|
GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread)
|
||||||
: QWidget(parent), emu_thread(emu_thread) {
|
: QWidget(parent), emu_thread(emu_thread) {
|
||||||
setWindowTitle(QStringLiteral("yuzu %1 | %2-%3")
|
setWindowTitle(QStringLiteral("yuzu %1 | %2-%3")
|
||||||
.arg(Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc));
|
.arg(QString::fromUtf8(Common::g_build_name),
|
||||||
|
QString::fromUtf8(Common::g_scm_branch),
|
||||||
|
QString::fromUtf8(Common::g_scm_desc)));
|
||||||
setAttribute(Qt::WA_AcceptTouchEvents);
|
setAttribute(Qt::WA_AcceptTouchEvents);
|
||||||
|
|
||||||
InputCommon::Init();
|
InputCommon::Init();
|
||||||
|
@ -217,7 +219,7 @@ void GRenderWindow::SwapBuffers() {
|
||||||
// However:
|
// However:
|
||||||
// - The Qt debug runtime prints a bogus warning on the console if `makeCurrent` wasn't called
|
// - The Qt debug runtime prints a bogus warning on the console if `makeCurrent` wasn't called
|
||||||
// since the last time `swapBuffers` was executed;
|
// since the last time `swapBuffers` was executed;
|
||||||
// - On macOS, if `makeCurrent` isn't called explicitely, resizing the buffer breaks.
|
// - On macOS, if `makeCurrent` isn't called explicitly, resizing the buffer breaks.
|
||||||
context->makeCurrent(child);
|
context->makeCurrent(child);
|
||||||
|
|
||||||
context->swapBuffers(child);
|
context->swapBuffers(child);
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QThreadPool>
|
#include <QThreadPool>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include "common/common_paths.h"
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/file_sys/patch_manager.h"
|
#include "core/file_sys/patch_manager.h"
|
||||||
|
@ -48,7 +47,7 @@ bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* eve
|
||||||
return QObject::eventFilter(obj, event);
|
return QObject::eventFilter(obj, event);
|
||||||
} else {
|
} else {
|
||||||
gamelist->search_field->edit_filter->clear();
|
gamelist->search_field->edit_filter->clear();
|
||||||
edit_filter_text = "";
|
edit_filter_text.clear();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -71,9 +70,9 @@ bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* eve
|
||||||
}
|
}
|
||||||
if (resultCount == 1) {
|
if (resultCount == 1) {
|
||||||
// To avoid loading error dialog loops while confirming them using enter
|
// To avoid loading error dialog loops while confirming them using enter
|
||||||
// Also users usually want to run a diffrent game after closing one
|
// Also users usually want to run a different game after closing one
|
||||||
gamelist->search_field->edit_filter->setText("");
|
gamelist->search_field->edit_filter->clear();
|
||||||
edit_filter_text = "";
|
edit_filter_text.clear();
|
||||||
emit gamelist->GameChosen(file_path);
|
emit gamelist->GameChosen(file_path);
|
||||||
} else {
|
} else {
|
||||||
return QObject::eventFilter(obj, event);
|
return QObject::eventFilter(obj, event);
|
||||||
|
@ -93,7 +92,7 @@ void GameListSearchField::setFilterResult(int visible, int total) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameListSearchField::clear() {
|
void GameListSearchField::clear() {
|
||||||
edit_filter->setText("");
|
edit_filter->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameListSearchField::setFocus() {
|
void GameListSearchField::setFocus() {
|
||||||
|
@ -103,25 +102,26 @@ void GameListSearchField::setFocus() {
|
||||||
}
|
}
|
||||||
|
|
||||||
GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} {
|
GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} {
|
||||||
KeyReleaseEater* keyReleaseEater = new KeyReleaseEater(parent);
|
auto* const key_release_eater = new KeyReleaseEater(parent);
|
||||||
layout_filter = new QHBoxLayout;
|
layout_filter = new QHBoxLayout;
|
||||||
layout_filter->setMargin(8);
|
layout_filter->setMargin(8);
|
||||||
label_filter = new QLabel;
|
label_filter = new QLabel;
|
||||||
label_filter->setText(tr("Filter:"));
|
label_filter->setText(tr("Filter:"));
|
||||||
edit_filter = new QLineEdit;
|
edit_filter = new QLineEdit;
|
||||||
edit_filter->setText("");
|
edit_filter->clear();
|
||||||
edit_filter->setPlaceholderText(tr("Enter pattern to filter"));
|
edit_filter->setPlaceholderText(tr("Enter pattern to filter"));
|
||||||
edit_filter->installEventFilter(keyReleaseEater);
|
edit_filter->installEventFilter(key_release_eater);
|
||||||
edit_filter->setClearButtonEnabled(true);
|
edit_filter->setClearButtonEnabled(true);
|
||||||
connect(edit_filter, &QLineEdit::textChanged, parent, &GameList::onTextChanged);
|
connect(edit_filter, &QLineEdit::textChanged, parent, &GameList::onTextChanged);
|
||||||
label_filter_result = new QLabel;
|
label_filter_result = new QLabel;
|
||||||
button_filter_close = new QToolButton(this);
|
button_filter_close = new QToolButton(this);
|
||||||
button_filter_close->setText("X");
|
button_filter_close->setText(QStringLiteral("X"));
|
||||||
button_filter_close->setCursor(Qt::ArrowCursor);
|
button_filter_close->setCursor(Qt::ArrowCursor);
|
||||||
button_filter_close->setStyleSheet("QToolButton{ border: none; padding: 0px; color: "
|
button_filter_close->setStyleSheet(
|
||||||
"#000000; font-weight: bold; background: #F0F0F0; }"
|
QStringLiteral("QToolButton{ border: none; padding: 0px; color: "
|
||||||
"QToolButton:hover{ border: none; padding: 0px; color: "
|
"#000000; font-weight: bold; background: #F0F0F0; }"
|
||||||
"#EEEEEE; font-weight: bold; background: #E81123}");
|
"QToolButton:hover{ border: none; padding: 0px; color: "
|
||||||
|
"#EEEEEE; font-weight: bold; background: #E81123}"));
|
||||||
connect(button_filter_close, &QToolButton::clicked, parent, &GameList::onFilterCloseClicked);
|
connect(button_filter_close, &QToolButton::clicked, parent, &GameList::onFilterCloseClicked);
|
||||||
layout_filter->setSpacing(10);
|
layout_filter->setSpacing(10);
|
||||||
layout_filter->addWidget(label_filter);
|
layout_filter->addWidget(label_filter);
|
||||||
|
@ -141,36 +141,34 @@ GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} {
|
||||||
*/
|
*/
|
||||||
static bool ContainsAllWords(const QString& haystack, const QString& userinput) {
|
static bool ContainsAllWords(const QString& haystack, const QString& userinput) {
|
||||||
const QStringList userinput_split =
|
const QStringList userinput_split =
|
||||||
userinput.split(' ', QString::SplitBehavior::SkipEmptyParts);
|
userinput.split(QLatin1Char{' '}, QString::SplitBehavior::SkipEmptyParts);
|
||||||
|
|
||||||
return std::all_of(userinput_split.begin(), userinput_split.end(),
|
return std::all_of(userinput_split.begin(), userinput_split.end(),
|
||||||
[&haystack](const QString& s) { return haystack.contains(s); });
|
[&haystack](const QString& s) { return haystack.contains(s); });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Event in order to filter the gamelist after editing the searchfield
|
// Event in order to filter the gamelist after editing the searchfield
|
||||||
void GameList::onTextChanged(const QString& newText) {
|
void GameList::onTextChanged(const QString& new_text) {
|
||||||
int rowCount = tree_view->model()->rowCount();
|
const int row_count = tree_view->model()->rowCount();
|
||||||
QString edit_filter_text = newText.toLower();
|
const QString edit_filter_text = new_text.toLower();
|
||||||
|
const QModelIndex root_index = item_model->invisibleRootItem()->index();
|
||||||
QModelIndex root_index = item_model->invisibleRootItem()->index();
|
|
||||||
|
|
||||||
// If the searchfield is empty every item is visible
|
// If the searchfield is empty every item is visible
|
||||||
// Otherwise the filter gets applied
|
// Otherwise the filter gets applied
|
||||||
if (edit_filter_text.isEmpty()) {
|
if (edit_filter_text.isEmpty()) {
|
||||||
for (int i = 0; i < rowCount; ++i) {
|
for (int i = 0; i < row_count; ++i) {
|
||||||
tree_view->setRowHidden(i, root_index, false);
|
tree_view->setRowHidden(i, root_index, false);
|
||||||
}
|
}
|
||||||
search_field->setFilterResult(rowCount, rowCount);
|
search_field->setFilterResult(row_count, row_count);
|
||||||
} else {
|
} else {
|
||||||
int result_count = 0;
|
int result_count = 0;
|
||||||
for (int i = 0; i < rowCount; ++i) {
|
for (int i = 0; i < row_count; ++i) {
|
||||||
const QStandardItem* child_file = item_model->item(i, 0);
|
const QStandardItem* child_file = item_model->item(i, 0);
|
||||||
const QString file_path =
|
const QString file_path =
|
||||||
child_file->data(GameListItemPath::FullPathRole).toString().toLower();
|
child_file->data(GameListItemPath::FullPathRole).toString().toLower();
|
||||||
QString file_name = file_path.mid(file_path.lastIndexOf('/') + 1);
|
|
||||||
const QString file_title =
|
const QString file_title =
|
||||||
child_file->data(GameListItemPath::TitleRole).toString().toLower();
|
child_file->data(GameListItemPath::TitleRole).toString().toLower();
|
||||||
const QString file_programmid =
|
const QString file_program_id =
|
||||||
child_file->data(GameListItemPath::ProgramIdRole).toString().toLower();
|
child_file->data(GameListItemPath::ProgramIdRole).toString().toLower();
|
||||||
|
|
||||||
// Only items which filename in combination with its title contains all words
|
// Only items which filename in combination with its title contains all words
|
||||||
|
@ -178,14 +176,16 @@ void GameList::onTextChanged(const QString& newText) {
|
||||||
// The search is case insensitive because of toLower()
|
// The search is case insensitive because of toLower()
|
||||||
// I decided not to use Qt::CaseInsensitive in containsAllWords to prevent
|
// I decided not to use Qt::CaseInsensitive in containsAllWords to prevent
|
||||||
// multiple conversions of edit_filter_text for each game in the gamelist
|
// multiple conversions of edit_filter_text for each game in the gamelist
|
||||||
if (ContainsAllWords(file_name.append(' ').append(file_title), edit_filter_text) ||
|
const QString file_name = file_path.mid(file_path.lastIndexOf(QLatin1Char{'/'}) + 1) +
|
||||||
(file_programmid.count() == 16 && edit_filter_text.contains(file_programmid))) {
|
QLatin1Char{' '} + file_title;
|
||||||
|
if (ContainsAllWords(file_name, edit_filter_text) ||
|
||||||
|
(file_program_id.count() == 16 && edit_filter_text.contains(file_program_id))) {
|
||||||
tree_view->setRowHidden(i, root_index, false);
|
tree_view->setRowHidden(i, root_index, false);
|
||||||
++result_count;
|
++result_count;
|
||||||
} else {
|
} else {
|
||||||
tree_view->setRowHidden(i, root_index, true);
|
tree_view->setRowHidden(i, root_index, true);
|
||||||
}
|
}
|
||||||
search_field->setFilterResult(result_count, rowCount);
|
search_field->setFilterResult(result_count, row_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,7 +216,7 @@ GameList::GameList(FileSys::VirtualFilesystem vfs, FileSys::ManualContentProvide
|
||||||
tree_view->setEditTriggers(QHeaderView::NoEditTriggers);
|
tree_view->setEditTriggers(QHeaderView::NoEditTriggers);
|
||||||
tree_view->setUniformRowHeights(true);
|
tree_view->setUniformRowHeights(true);
|
||||||
tree_view->setContextMenuPolicy(Qt::CustomContextMenu);
|
tree_view->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
tree_view->setStyleSheet("QTreeView{ border: none; }");
|
tree_view->setStyleSheet(QStringLiteral("QTreeView{ border: none; }"));
|
||||||
|
|
||||||
item_model->insertColumns(0, UISettings::values.show_add_ons ? COLUMN_COUNT : COLUMN_COUNT - 1);
|
item_model->insertColumns(0, UISettings::values.show_add_ons ? COLUMN_COUNT : COLUMN_COUNT - 1);
|
||||||
item_model->setHeaderData(COLUMN_NAME, Qt::Horizontal, tr("Name"));
|
item_model->setHeaderData(COLUMN_NAME, Qt::Horizontal, tr("Name"));
|
||||||
|
@ -282,9 +282,9 @@ void GameList::ValidateEntry(const QModelIndex& item) {
|
||||||
const QFileInfo file_info{file_path};
|
const QFileInfo file_info{file_path};
|
||||||
if (file_info.isDir()) {
|
if (file_info.isDir()) {
|
||||||
const QDir dir{file_path};
|
const QDir dir{file_path};
|
||||||
const QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files);
|
const QStringList matching_main = dir.entryList({QStringLiteral("main")}, QDir::Files);
|
||||||
if (matching_main.size() == 1) {
|
if (matching_main.size() == 1) {
|
||||||
emit GameChosen(dir.path() + DIR_SEP + matching_main[0]);
|
emit GameChosen(dir.path() + QDir::separator() + matching_main[0]);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -360,7 +360,7 @@ void GameList::PopupContextMenu(const QPoint& menu_location) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameList::LoadCompatibilityList() {
|
void GameList::LoadCompatibilityList() {
|
||||||
QFile compat_list{":compatibility_list/compatibility_list.json"};
|
QFile compat_list{QStringLiteral(":compatibility_list/compatibility_list.json")};
|
||||||
|
|
||||||
if (!compat_list.open(QFile::ReadOnly | QFile::Text)) {
|
if (!compat_list.open(QFile::ReadOnly | QFile::Text)) {
|
||||||
LOG_ERROR(Frontend, "Unable to open game compatibility list");
|
LOG_ERROR(Frontend, "Unable to open game compatibility list");
|
||||||
|
@ -378,25 +378,27 @@ void GameList::LoadCompatibilityList() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString string_content = content;
|
const QJsonDocument json = QJsonDocument::fromJson(content);
|
||||||
QJsonDocument json = QJsonDocument::fromJson(string_content.toUtf8());
|
const QJsonArray arr = json.array();
|
||||||
QJsonArray arr = json.array();
|
|
||||||
|
|
||||||
for (const QJsonValueRef value : arr) {
|
for (const QJsonValue value : arr) {
|
||||||
QJsonObject game = value.toObject();
|
const QJsonObject game = value.toObject();
|
||||||
|
const QString compatibility_key = QStringLiteral("compatibility");
|
||||||
|
|
||||||
if (game.contains("compatibility") && game["compatibility"].isDouble()) {
|
if (!game.contains(compatibility_key) || !game[compatibility_key].isDouble()) {
|
||||||
int compatibility = game["compatibility"].toInt();
|
continue;
|
||||||
QString directory = game["directory"].toString();
|
}
|
||||||
QJsonArray ids = game["releases"].toArray();
|
|
||||||
|
|
||||||
for (const QJsonValueRef id_ref : ids) {
|
const int compatibility = game[compatibility_key].toInt();
|
||||||
QJsonObject id_object = id_ref.toObject();
|
const QString directory = game[QStringLiteral("directory")].toString();
|
||||||
QString id = id_object["id"].toString();
|
const QJsonArray ids = game[QStringLiteral("releases")].toArray();
|
||||||
compatibility_list.emplace(
|
|
||||||
id.toUpper().toStdString(),
|
for (const QJsonValue id_ref : ids) {
|
||||||
std::make_pair(QString::number(compatibility), directory));
|
const QJsonObject id_object = id_ref.toObject();
|
||||||
}
|
const QString id = id_object[QStringLiteral("id")].toString();
|
||||||
|
|
||||||
|
compatibility_list.emplace(id.toUpper().toStdString(),
|
||||||
|
std::make_pair(QString::number(compatibility), directory));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -464,7 +466,10 @@ void GameList::LoadInterfaceLayout() {
|
||||||
item_model->sort(header->sortIndicatorSection(), header->sortIndicatorOrder());
|
item_model->sort(header->sortIndicatorSection(), header->sortIndicatorOrder());
|
||||||
}
|
}
|
||||||
|
|
||||||
const QStringList GameList::supported_file_extensions = {"nso", "nro", "nca", "xci", "nsp"};
|
const QStringList GameList::supported_file_extensions = {
|
||||||
|
QStringLiteral("nso"), QStringLiteral("nro"), QStringLiteral("nca"),
|
||||||
|
QStringLiteral("xci"), QStringLiteral("nsp"),
|
||||||
|
};
|
||||||
|
|
||||||
void GameList::RefreshGameDirectory() {
|
void GameList::RefreshGameDirectory() {
|
||||||
if (!UISettings::values.game_directory_path.isEmpty() && current_worker != nullptr) {
|
if (!UISettings::values.game_directory_path.isEmpty() && current_worker != nullptr) {
|
||||||
|
|
|
@ -76,7 +76,7 @@ signals:
|
||||||
void OpenPerGameGeneralRequested(const std::string& file);
|
void OpenPerGameGeneralRequested(const std::string& file);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onTextChanged(const QString& newText);
|
void onTextChanged(const QString& new_text);
|
||||||
void onFilterCloseClicked();
|
void onFilterCloseClicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -4,11 +4,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
@ -25,8 +23,8 @@
|
||||||
#include "yuzu/util/util.h"
|
#include "yuzu/util/util.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the default icon (for games without valid SMDH)
|
* Gets the default icon (for games without valid title metadata)
|
||||||
* @param large If true, returns large icon (48x48), otherwise returns small icon (24x24)
|
* @param size The desired width and height of the default icon.
|
||||||
* @return QPixmap default icon
|
* @return QPixmap default icon
|
||||||
*/
|
*/
|
||||||
static QPixmap GetDefaultIcon(u32 size) {
|
static QPixmap GetDefaultIcon(u32 size) {
|
||||||
|
@ -46,7 +44,7 @@ public:
|
||||||
* A specialization of GameListItem for path values.
|
* A specialization of GameListItem for path values.
|
||||||
* This class ensures that for every full path value it holds, a correct string representation
|
* This class ensures that for every full path value it holds, a correct string representation
|
||||||
* of just the filename (with no extension) will be displayed to the user.
|
* of just the filename (with no extension) will be displayed to the user.
|
||||||
* If this class receives valid SMDH data, it will also display game icons and titles.
|
* If this class receives valid title metadata, it will also display game icons and titles.
|
||||||
*/
|
*/
|
||||||
class GameListItemPath : public GameListItem {
|
class GameListItemPath : public GameListItem {
|
||||||
public:
|
public:
|
||||||
|
@ -95,7 +93,7 @@ public:
|
||||||
if (row2.isEmpty())
|
if (row2.isEmpty())
|
||||||
return row1;
|
return row1;
|
||||||
|
|
||||||
return QString(row1 + "\n " + row2);
|
return QString(row1 + QStringLiteral("\n ") + row2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GameListItem::data(role);
|
return GameListItem::data(role);
|
||||||
|
@ -115,13 +113,14 @@ public:
|
||||||
};
|
};
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const std::map<QString, CompatStatus> status_data = {
|
static const std::map<QString, CompatStatus> status_data = {
|
||||||
{"0", {"#5c93ed", QT_TR_NOOP("Perfect"), QT_TR_NOOP("Game functions flawless with no audio or graphical glitches, all tested functionality works as intended without\nany workarounds needed.")}},
|
{QStringLiteral("0"), {QStringLiteral("#5c93ed"), QT_TR_NOOP("Perfect"), QT_TR_NOOP("Game functions flawless with no audio or graphical glitches, all tested functionality works as intended without\nany workarounds needed.")}},
|
||||||
{"1", {"#47d35c", QT_TR_NOOP("Great"), QT_TR_NOOP("Game functions with minor graphical or audio glitches and is playable from start to finish. May require some\nworkarounds.")}},
|
{QStringLiteral("1"), {QStringLiteral("#47d35c"), QT_TR_NOOP("Great"), QT_TR_NOOP("Game functions with minor graphical or audio glitches and is playable from start to finish. May require some\nworkarounds.")}},
|
||||||
{"2", {"#94b242", QT_TR_NOOP("Okay"), QT_TR_NOOP("Game functions with major graphical or audio glitches, but game is playable from start to finish with\nworkarounds.")}},
|
{QStringLiteral("2"), {QStringLiteral("#94b242"), QT_TR_NOOP("Okay"), QT_TR_NOOP("Game functions with major graphical or audio glitches, but game is playable from start to finish with\nworkarounds.")}},
|
||||||
{"3", {"#f2d624", QT_TR_NOOP("Bad"), QT_TR_NOOP("Game functions, but with major graphical or audio glitches. Unable to progress in specific areas due to glitches\neven with workarounds.")}},
|
{QStringLiteral("3"), {QStringLiteral("#f2d624"), QT_TR_NOOP("Bad"), QT_TR_NOOP("Game functions, but with major graphical or audio glitches. Unable to progress in specific areas due to glitches\neven with workarounds.")}},
|
||||||
{"4", {"#FF0000", QT_TR_NOOP("Intro/Menu"), QT_TR_NOOP("Game is completely unplayable due to major graphical or audio glitches. Unable to progress past the Start\nScreen.")}},
|
{QStringLiteral("4"), {QStringLiteral("#FF0000"), QT_TR_NOOP("Intro/Menu"), QT_TR_NOOP("Game is completely unplayable due to major graphical or audio glitches. Unable to progress past the Start\nScreen.")}},
|
||||||
{"5", {"#828282", QT_TR_NOOP("Won't Boot"), QT_TR_NOOP("The game crashes when attempting to startup.")}},
|
{QStringLiteral("5"), {QStringLiteral("#828282"), QT_TR_NOOP("Won't Boot"), QT_TR_NOOP("The game crashes when attempting to startup.")}},
|
||||||
{"99", {"#000000", QT_TR_NOOP("Not Tested"), QT_TR_NOOP("The game has not yet been tested.")}}};
|
{QStringLiteral("99"), {QStringLiteral("#000000"), QT_TR_NOOP("Not Tested"), QT_TR_NOOP("The game has not yet been tested.")}},
|
||||||
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
auto iterator = status_data.find(compatibility);
|
auto iterator = status_data.find(compatibility);
|
||||||
|
|
|
@ -45,7 +45,7 @@ bool HasSupportedFileExtension(const std::string& file_name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsExtractedNCAMain(const std::string& file_name) {
|
bool IsExtractedNCAMain(const std::string& file_name) {
|
||||||
return QFileInfo(QString::fromStdString(file_name)).fileName() == "main";
|
return QFileInfo(QString::fromStdString(file_name)).fileName() == QStringLiteral("main");
|
||||||
}
|
}
|
||||||
|
|
||||||
QString FormatGameName(const std::string& physical_name) {
|
QString FormatGameName(const std::string& physical_name) {
|
||||||
|
@ -97,7 +97,7 @@ QList<QStandardItem*> MakeGameListEntry(const std::string& path, const std::stri
|
||||||
const auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
|
const auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
|
||||||
|
|
||||||
// The game list uses this as compatibility number for untested games
|
// The game list uses this as compatibility number for untested games
|
||||||
QString compatibility{"99"};
|
QString compatibility{QStringLiteral("99")};
|
||||||
if (it != compatibility_list.end()) {
|
if (it != compatibility_list.end()) {
|
||||||
compatibility = it->second.first;
|
compatibility = it->second.first;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,11 +30,11 @@
|
||||||
#include <QMovie>
|
#include <QMovie>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
constexpr const char PROGRESSBAR_STYLE_PREPARE[] = R"(
|
constexpr char PROGRESSBAR_STYLE_PREPARE[] = R"(
|
||||||
QProgressBar {}
|
QProgressBar {}
|
||||||
QProgressBar::chunk {})";
|
QProgressBar::chunk {})";
|
||||||
|
|
||||||
constexpr const char PROGRESSBAR_STYLE_DECOMPILE[] = R"(
|
constexpr char PROGRESSBAR_STYLE_DECOMPILE[] = R"(
|
||||||
QProgressBar {
|
QProgressBar {
|
||||||
background-color: black;
|
background-color: black;
|
||||||
border: 2px solid white;
|
border: 2px solid white;
|
||||||
|
@ -46,7 +46,7 @@ QProgressBar::chunk {
|
||||||
width: 1px;
|
width: 1px;
|
||||||
})";
|
})";
|
||||||
|
|
||||||
constexpr const char PROGRESSBAR_STYLE_BUILD[] = R"(
|
constexpr char PROGRESSBAR_STYLE_BUILD[] = R"(
|
||||||
QProgressBar {
|
QProgressBar {
|
||||||
background-color: black;
|
background-color: black;
|
||||||
border: 2px solid white;
|
border: 2px solid white;
|
||||||
|
@ -58,7 +58,7 @@ QProgressBar::chunk {
|
||||||
width: 1px;
|
width: 1px;
|
||||||
})";
|
})";
|
||||||
|
|
||||||
constexpr const char PROGRESSBAR_STYLE_COMPLETE[] = R"(
|
constexpr char PROGRESSBAR_STYLE_COMPLETE[] = R"(
|
||||||
QProgressBar {
|
QProgressBar {
|
||||||
background-color: #0ab9e6;
|
background-color: #0ab9e6;
|
||||||
border: 2px solid white;
|
border: 2px solid white;
|
||||||
|
@ -149,10 +149,10 @@ void LoadingScreen::OnLoadComplete() {
|
||||||
void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value,
|
void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value,
|
||||||
std::size_t total) {
|
std::size_t total) {
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
auto now = high_resolution_clock::now();
|
const auto now = high_resolution_clock::now();
|
||||||
// reset the timer if the stage changes
|
// reset the timer if the stage changes
|
||||||
if (stage != previous_stage) {
|
if (stage != previous_stage) {
|
||||||
ui->progress_bar->setStyleSheet(progressbar_style[stage]);
|
ui->progress_bar->setStyleSheet(QString::fromUtf8(progressbar_style[stage]));
|
||||||
// Hide the progress bar during the prepare stage
|
// Hide the progress bar during the prepare stage
|
||||||
if (stage == VideoCore::LoadCallbackStage::Prepare) {
|
if (stage == VideoCore::LoadCallbackStage::Prepare) {
|
||||||
ui->progress_bar->hide();
|
ui->progress_bar->hide();
|
||||||
|
@ -178,16 +178,16 @@ void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size
|
||||||
slow_shader_first_value = value;
|
slow_shader_first_value = value;
|
||||||
}
|
}
|
||||||
// only calculate an estimate time after a second has passed since stage change
|
// only calculate an estimate time after a second has passed since stage change
|
||||||
auto diff = duration_cast<milliseconds>(now - slow_shader_start);
|
const auto diff = duration_cast<milliseconds>(now - slow_shader_start);
|
||||||
if (diff > seconds{1}) {
|
if (diff > seconds{1}) {
|
||||||
auto eta_mseconds =
|
const auto eta_mseconds =
|
||||||
static_cast<long>(static_cast<double>(total - slow_shader_first_value) /
|
static_cast<long>(static_cast<double>(total - slow_shader_first_value) /
|
||||||
(value - slow_shader_first_value) * diff.count());
|
(value - slow_shader_first_value) * diff.count());
|
||||||
estimate =
|
estimate =
|
||||||
tr("Estimated Time %1")
|
tr("Estimated Time %1")
|
||||||
.arg(QTime(0, 0, 0, 0)
|
.arg(QTime(0, 0, 0, 0)
|
||||||
.addMSecs(std::max<long>(eta_mseconds - diff.count() + 1000, 1000))
|
.addMSecs(std::max<long>(eta_mseconds - diff.count() + 1000, 1000))
|
||||||
.toString("mm:ss"));
|
.toString(QStringLiteral("mm:ss")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "yuzu/util/util.h"
|
#include "yuzu/util/util.h"
|
||||||
|
|
||||||
QFont GetMonospaceFont() {
|
QFont GetMonospaceFont() {
|
||||||
QFont font("monospace");
|
QFont font(QStringLiteral("monospace"));
|
||||||
// Automatic fallback to a monospace font on on platforms without a font called "monospace"
|
// Automatic fallback to a monospace font on on platforms without a font called "monospace"
|
||||||
font.setStyleHint(QFont::Monospace);
|
font.setStyleHint(QFont::Monospace);
|
||||||
font.setFixedPitch(true);
|
font.setFixedPitch(true);
|
||||||
|
@ -16,14 +16,16 @@ QFont GetMonospaceFont() {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ReadableByteSize(qulonglong size) {
|
QString ReadableByteSize(qulonglong size) {
|
||||||
static const std::array<const char*, 6> units = {"B", "KiB", "MiB", "GiB", "TiB", "PiB"};
|
static constexpr std::array units{"B", "KiB", "MiB", "GiB", "TiB", "PiB"};
|
||||||
if (size == 0)
|
if (size == 0) {
|
||||||
return "0";
|
return QStringLiteral("0");
|
||||||
int digit_groups = std::min<int>(static_cast<int>(std::log10(size) / std::log10(1024)),
|
}
|
||||||
static_cast<int>(units.size()));
|
|
||||||
return QString("%L1 %2")
|
const int digit_groups = std::min(static_cast<int>(std::log10(size) / std::log10(1024)),
|
||||||
|
static_cast<int>(units.size()));
|
||||||
|
return QStringLiteral("%L1 %2")
|
||||||
.arg(size / std::pow(1024, digit_groups), 0, 'f', 1)
|
.arg(size / std::pow(1024, digit_groups), 0, 'f', 1)
|
||||||
.arg(units[digit_groups]);
|
.arg(QString::fromUtf8(units[digit_groups]));
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap CreateCirclePixmapFromColor(const QColor& color) {
|
QPixmap CreateCirclePixmapFromColor(const QColor& color) {
|
||||||
|
|
Loading…
Reference in a new issue